简体   繁体   English

$(document).ready 在 JavaScript 中等效

[英]$(document).ready equivalant in JavaScript

I try to find equivalent code for jQuery $(document).ready, and find there are some different versions:我尝试找到 jQuery $(document).ready 的等效代码,并发现有一些不同的版本:

Version 1:版本 1:

function ready(fn) {
  if (document.readyState != 'loading'){
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

Version 2:版本 2:

document.addEventListener('DOMContentLoaded', fn);

What is the difference?有什么不同? Why version 1 will check document.readyState?为什么版本 1 会检查 document.readyState? Also version 1 is a function, while version 2 is an executed statement.此外,版本 1 是一个函数,而版本 2 是一个已执行的语句。 So should there be one statement for version 1:因此,版本 1 是否应该有一个声明:

ready(fn);

The difference is that the first one will work even if the script is executed after DOMContentLoaded has fired (see document.readyState for more), provided you add the call to ready you asked about.不同之处在于,即使脚本在DOMContentLoaded触发后执行(更多信息请参见document.readyState ),第一个也能工作,前提是您将调用添加到您所询问的ready The second won't, because the event is only fired once, so if the script is executed after that, fn will never get called.第二个不会,因为事件只触发一次,所以如果脚本在那之后执行, fn将永远不会被调用。

So how could the script be executed after the event has already fired?那么如何在事件触发后执行脚本呢? Basically, if it's added dynamically, not as part of the document's initial HTML.基本上,如果它是动态添加的,而不是作为文档初始 HTML 的一部分。 Here are a couple of examples of how that could be:以下是一些示例,说明如何做到这一点:

  • A script element added after the document has loaded.在文档加载后添加的script元素。
  • A module loaded via dynamic import() rather than static import .通过动态import()而不是静态import加载的模块。

There are probably others.可能还有其他人。

Also version 1 is a function, while version 2 is an executed statement.此外,版本 1 是一个函数,而版本 2 是一个已执行的语句。 So should there be one statement for version 1:因此,版本 1 是否应该有一个声明:

 ready(fn);

Yes, absolutely right.是的,完全正确。


I should note that you don't need either of those if you control how the script is included in the page.我应该注意,如果您控制脚本在页面中的包含方式,则不需要其中任何一个。 (So, you do need it in libraries, but rarely in apps/pages.) If you control how the script is included in the page, and want your code to run after the DOM has been built, here are several ways you can do that (IMHO, in order of best practice): (因此,您确实在库中需要它,但在应用程序/页面中很少需要它。)如果您控制脚本在页面中的包含方式,并希望您的代码在 DOM 构建后运行,您可以通过以下几种方式进行操作那个(恕我直言,按照最佳实践的顺序):

  • Use type="module" on the script to make it a module.在脚本上使用type="module"使其成为模块。 Modules aren't executed until the DOM has been built (they're auto-deferred, even inline modules; see the next bullet point).在构建 DOM 之前不会执行模块(它们是自动延迟的,甚至是内联模块;请参阅下一个要点)。
  • Use defer on your script tag (only works for src script tags referring to files, not inline scripts).在您的script标签上使用defer (仅适用于引用文件的src脚本标签,不适用于内联脚本)。 Deferred scripts aren't executed until the DOM has been built.在构建 DOM 之前,不会执行延迟脚本。
  • Put the script tag at the end of the document, just before the closing </body> tag.script标签放在文档的末尾,就在结束</body>标签之前。

If you do any of those things, there's no need to use ready (jQuery's or the ones in your question).如果您执行任何这些操作,则无需使用ready (jQuery 或您问题中的那些)。

The documentation of jQuery has the answer to your question. jQuery 的文档可以回答您的问题。

jQuery.ready() : jQuery.ready()

Most browsers provide similar functionality in the form of a DOMContentLoaded event.大多数浏览器都以DOMContentLoaded事件的形式提供类似的功能。 However, jQuery's .ready() method differs in an important and useful way: If the DOM becomes ready and the browser fires DOMContentLoaded before the code calls .ready( handler ) , the function handler will still be executed.但是,jQuery 的.ready()方法在一个重要且有用的方面有所不同:如果 DOM 准备就绪并且浏览器在代码调用.ready( handler )之前触发DOMContentLoaded ,则函数处理程序仍将被执行。 In contrast, a DOMContentLoaded event listener added after the event fires is never executed.…相比之下,在事件触发后添加的DOMContentLoaded事件侦听器永远不会执行。...

So your Version 2 has the described problem.所以你的版本 2有描述的问题。 While Version 1 calls the passed function even after the document is already ready.即使在文档已经准备好之后,版本 1也会调用传递的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM