Javascript 等待 ES6 模块中的文档就绪

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39722809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:49:57  来源:igfitidea点击:

Wait for document ready in ES6 modules

javascriptdomes6-modules

提问by hhh

With hoisting, ES6 modules are loaded before the document is ready.

通过提升,ES6 模块在文档准备好之前加载。

For example,

例如,

// module.js
console.log('body', document.body);
export let a = 1;

// main.js
import {a} from 'module'

log body nullin the console.

登录body null控制台。

How to have ES6 modules that use DOM manipulation and required document ready?

如何拥有使用 DOM 操作和必需的 ES6 模块document ready

I tried to use

我试着用

$(document).ready(function() {
  var a = 1;
});

export {a};

in my module but babel returned me an Unexpected tokenerror.

在我的模块中,但是 babel 返回了一个Unexpected token错误。

I also tried

我也试过

$(document).ready(function() {
  export let a = 1;
});

and I had an 'import' and 'export' may only appear at the top levelerror.

我有一个'import' and 'export' may only appear at the top level错误。

Update:

更新:

I have the same problem with

我有同样的问题

document.addEventListener("DOMContentLoaded",function(){
  var a = 1;
}

export {a};

because ais not defined.

因为a没有定义。

that is to say the variable to export are not available (see my update).

也就是说要导出的变量不可用(请参阅我的更新)。

Update:

更新:

Here is my attempt based on @MaciejSikora code:

这是我基于@MaciejSikora 代码的尝试:

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 widthis undefined.

width未定义。

回答by Maciej Sikora

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 ):

DOM 在 ES6 中没有改变,ES6 为 JavaScript 提供了新的特性,就是所有. 在纯 js 中,dom 加载的存在事件(它是 jquery 等价的文档):

document.addEventListener("DOMContentLoaded",function(){

    //here code
});

Modules working with DOM tree can have listener inside, or should be used after dom is ready. I created example DomManipulatecomponent to show what I mean:

使用 DOM 树的模块可以在里面有监听器,或者应该在 dom 准备好后使用。我创建了示例DomManipulate组件来说明我的意思:

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:

模块应该独立于 DOM,创建直接导出 DOM 元素的模块是非常错误的做法。所以它可以通过两种方式完成:

  1. 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.

  2. 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).

  1. 模块应该在属性中获取选择器 DOM 对象,并且应该在 DOM 准备好后调用。所以你的模块不知道在哪里被调用,但它需要准备好的 DOM 结构。在这种情况下,DOM 就绪回调仅在使用模块并调用它们的主文件中。

  2. 模块可以有一些 DOM 就绪侦听器,但我们还需要一些信息何时可以使用模块(我在示例和 onReady 函数中展示了这种情况)。

回答by Pranesh Ravi

Try to place your <script>tag at the bottom of <body/>. By doing this, document.bodywill be available and it won't throw an error.

尝试将您的<script>标签放在<body/>. 通过这样做,document.body将可用并且不会抛出错误。

回答by nimo23

If script is at bottom of the page then dom is already loaded, so no need for 'DOMContentLoaded'. Or?

如果脚本位于页面底部,则 dom 已经加载,因此不需要“DOMContentLoaded”。或者?