With hoisting, ES6 modules are loaded before the document is ready.
For example,
// module.js console.log('body', document.body); export let a = 1; // main.js import {a} from 'module'
log body null
in the console.
How to have ES6 modules that use DOM manipulation and required document ready
?
I tried to use
$(document).ready(function() { var a = 1; }); export {a};
in my module but babel returned me an Unexpected token
error.
I also tried
$(document).ready(function() { export let a = 1; });
and I had an 'import' and 'export' may only appear at the top level
error.
Update:
I have the same problem with
document.addEventListener("DOMContentLoaded",function(){ var a = 1; } export {a};
because a
is not defined.
that is to say the variable to export are not available (see my update).
Update:
Here is my attempt based on @MaciejSikora code:
function Test() { document.addEventListener("DOMContentLoaded",()=>{ this.width = $(window).width(); }); }; //example object method Test.prototype.getElement = function(el) { return this[el]; }; export { Test };
In another file I do
var test = new Test(); var width = test.getElement('width');
But width
is undefined.
Approach 1: Using the holdReady() method in the jQuery library and the setTimeout() method. First we set the parameter in the holdReady() method to true to hold the execution of the document. ready() method. Then, a timeout function with an appropriate delay time can be added using the setTimeout() method.
jQuery $(document). ready() Equivalent in JavaScriptThis event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.
So technically they are both the same. Not major difference between these two declaration. They used based on weather you use JavaScript then you should use $(document). ready declaration in other case you use jQuery library which is a part of JavaScript then you should use $(function) declaration.
$( document ). ready() ready() will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute. Code included inside $( window ).
DOM has not changed in ES6, ES6 gives new features to JavaScript, that is all. In pure js exists event for dom loaded ( it is document ready from jquery equivalent ):
document.addEventListener("DOMContentLoaded",function(){ //Your code here });
Modules working with DOM tree can have listener inside, or should be used after dom is ready. I created example DomManipulate
component to show what I mean:
var DomManipulate=function(selector){ document.addEventListener("DOMContentLoaded",()=>{ this.element=document.querySelector(selector); if (typeof this.callback === 'function') this.callback(); }); }; //HERE WE HAVE CALLBACK WHEN OUR MODULE CAN BE USED DomManipulate.prototype.onReady=function(callback){ this.callback=callback; }; DomManipulate.prototype.getElement=function(){ //example object method return this.element; }; DomManipulate.prototype.write=function(text){ return this.element.innerText=text; }; export { DomManipulate };
So it is better approach and we have encapsulated component.
Usage example:
var d=new DomManipulate("#test"); d.onReady(()=>{d.write("Test text");});
Modules should be DOM independent, creating modules which are exporting DOM elements directly are very wrong practice. So it can be done in two ways:
Modules should get selectors DOM object in attributes and should be called after DOM is ready. So Your module has no idea where is called, but it needs ready DOM structure. In this situation DOM ready callback is only in main file which is using modules and call them.
Modules can have some DOM ready listeners but also We need some information when module can be used ( this situation I showed in example and onReady function).
Try to place your <script>
tag at the bottom of <body/>
. By doing this, document.body
will be available and it won't throw an error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With