等待ES6模块中的文档准备就绪

had*_*enj 20 javascript dom es6-modules

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

例如,

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

// main.js
import {a} from 'module'
Run Code Online (Sandbox Code Playgroud)

登录body null控制台.

如何使用DOM操作并需要ES6模块document ready

我试着用

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

export {a};
Run Code Online (Sandbox Code Playgroud)

在我的模块中但是babel给我一个Unexpected token错误.

我也试过了

$(document).ready(function() {
  export let a = 1;
});
Run Code Online (Sandbox Code Playgroud)

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

更新:

我有同样的问题

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

export {a};
Run Code Online (Sandbox Code Playgroud)

因为a没有定义.

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

更新:

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

function Test() {

   document.addEventListener("DOMContentLoaded",()=>{
      this.width = $(window).width();
   });

};

//example object method
Test.prototype.getElement = function(el) {
   return this[el];

};


export { Test };
Run Code Online (Sandbox Code Playgroud)

在我做的另一个文件中

var test = new Test();
var width = test.getElement('width');
Run Code Online (Sandbox Code Playgroud)

但是width未定义.

Mac*_*ora 18

ES6中没有改变DOM,ES6为JavaScript提供了新功能,就是这样.在纯js中存在dom加载的事件(它是从jquery等效文件准备好的):

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

    //here code
});
Run Code Online (Sandbox Code Playgroud)

使用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 };
Run Code Online (Sandbox Code Playgroud)

所以它是更好的方法,我们有封装组件.

用法示例:

var d=new DomManipulate("#test");
d.onReady(()=>{d.write("Test text");});
Run Code Online (Sandbox Code Playgroud)

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

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

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


Pra*_*avi 5

尝试将<script>标记放在底部<body/>.通过这样做,document.body将可用,它不会抛出错误.

  • 更好的是在DOM上加载事件.我们的脚本可以在任何地方使用html. (2认同)

Tim*_*imo 5

还有另一个更短(旧)的vanillajs 表达式需要等待加载DOM

window.onload=function(){}
Run Code Online (Sandbox Code Playgroud)

ES6 与胖箭头函数相同:

window.onload=()=>{}
Run Code Online (Sandbox Code Playgroud)

  • @JulesColle `onload` 等待 DOM+images,`DOMContentLoaded` 仅等待 DOM。根据您的需求,这可能会或可能不会产生影响,但它并不完全等同。 (4认同)