简体   繁体   English

window.onload vs $(document).ready()

[英]window.onload vs $(document).ready()

JavaScript 的window.onload和 jQuery 的$(document).ready()方法有什么区别?

The ready event occurs after the HTML document has been loaded, while the onload event occurs later, when all content (eg images) also has been loaded. ready事件在 HTML 文档加载后发生,而onload事件发生在稍后,当所有内容(例如图像)也已加载时。

The onload event is a standard event in the DOM, while the ready event is specific to jQuery. onload事件是 DOM 中的标准事件,而ready事件是特定于 jQuery 的。 The purpose of the ready event is that it should occur as early as possible after the document has loaded, so that code that adds functionality to the elements in the page doesn't have to wait for all content to load. ready事件的目的是它应该在文档加载后尽早发生,以便为页面中的元素添加功能的代码不必等待所有内容加载完毕。

window.onload is the built-in JavaScript event, but as its implementation had subtle quirks across browsers (Firefox, Internet Explorer 6, Internet Explorer 8, and Opera ), jQuery provides document.ready , which abstracts those away, and fires as soon as the page's DOM is ready (doesn't wait for images, etc.). window.onload是内置的 JavaScript 事件,但由于它的实现在浏览器(Firefox、Internet Explorer 6、Internet Explorer 8 和Opera )之间有微妙的怪癖,jQuery 提供了document.ready ,它将这些事件抽象化,并尽快触发因为页面的 DOM 已准备就绪(不等待图像等)。

$(document).ready (note that it's not document.ready , which is undefined) is a jQuery function, wrapping and providing consistency to the following events: $(document).ready (注意它不是document.ready ,它是未定义的)是一个 jQuery 函数,它包装并为以下事件提供一致性

  • document.ondomcontentready / document.ondomcontentloaded - a newish event which fires when the document's DOM is loaded (which may be some time before the images, etc. are loaded); document.ondomcontentready / document.ondomcontentloaded - 一个新事件,当文档的 DOM 被加载时触发(这可能是加载图像之前的一段时间); again, slightly different in Internet Explorer and in rest of the world再次,在 Internet Explorer 和世界其他地方略有不同
  • and window.onload (which is implemented even in old browsers), which fires when the entire page loads (images, styles, etc.)window.onload (即使在旧浏览器中也实现),当整个页面加载(图像、样式等)时触发

$(document).ready() is a jQuery event. $(document).ready()是一个 jQuery 事件。 JQuery's $(document).ready() method gets called as soon as the DOM is ready (which means that the browser has parsed the HTML and built the DOM tree). JQuery 的$(document).ready()方法会在 DOM 准备好后立即被调用(这意味着浏览器已经解析了 HTML 并构建了 DOM 树)。 This allows you to run code as soon as the document is ready to be manipulated.这使您可以在文档准备好进行操作时立即运行代码。

For example, if a browser supports the DOMContentLoaded event (as many non-IE browsers do), then it will fire on that event.例如,如果浏览器支持 DOMContentLoaded 事件(就像许多非 IE 浏览器一样),那么它将在该事件上触发。 (Note that the DOMContentLoaded event was only added to IE in IE9+.) (注意 DOMContentLoaded 事件仅在 IE9+ 中添加到 IE 中。)

Two syntaxes can be used for this:为此可以使用两种语法:

$( document ).ready(function() {
   console.log( "ready!" );
});

Or the shorthand version:或者简写版本:

$(function() {
   console.log( "ready!" );
});

Main points for $(document).ready() : $(document).ready()要点:

  • It will not wait for the images to be loaded.它不会等待图像加载。
  • Used to execute JavaScript when the DOM is completely loaded.用于在 DOM 完全加载时执行 JavaScript。 Put event handlers here.将事件处理程序放在这里。
  • Can be used multiple times.可以多次使用。
  • Replace $ with jQuery when you receive "$ is not defined."当您收到“$ 未定义”时,将$替换$ jQuery
  • Not used if you want to manipulate images.如果要操作图像,则不使用。 Use $(window).load() instead.使用$(window).load()代替。

window.onload() is a native JavaScript function. window.onload()是一个原生的 JavaScript 函数。 The window.onload() event fires when all the content on your page has loaded, including the DOM (document object model), banner ads and images. window.onload()事件在页面上的所有内容都加载window.onload()触发,包括 DOM(文档对象模型)、横幅广告和图像。 Another difference between the two is that, while we can have more than one $(document).ready() function, we can only have one onload function.两者之间的另一个区别是,虽然我们可以有多个$(document).ready()函数,但我们只能有一个onload函数。

A Windows load event fires when all the content on your page is fully loaded including the DOM (document object model) content and asynchronous JavaScript , frames and images .当页面上的所有内容都完全加载时, Windows 加载事件会触发,包括 DOM(文档对象模型)内容和异步 JavaScript框架和图像 You can also use body onload=.您也可以使用 body onload=。 Both are the same;两者都是一样的; window.onload = function(){} and <body onload="func();"> are different ways of using the same event. window.onload = function(){}<body onload="func();">是使用相同事件的不同方式。

jQuery $document.ready function event executes a bit earlier than window.onload and is called once the DOM(Document object model) is loaded on your page. jQuery $document.ready函数事件比window.onload早一点执行,并且在页面上加载 DOM(文档对象模型)后调用。 It will not wait for the images, frames to get fully load .它不会等待图像、帧完全加载

Taken from the following article: how $document.ready() is different from window.onload()摘自以下文章: $document.ready()window.onload()有何不同

A little tip:一个小技巧:

Always use the window.addEventListener to add an event to window.始终使用window.addEventListener向窗口添加事件。 Because that way you can execute the code in different event handlers .因为这样您就可以在不同的事件处理程序中执行代码。

Correct code:正确代码:

 window.addEventListener('load', function () { alert('Hello!') }) window.addEventListener('load', function () { alert('Bye!') })

Invalid code:无效代码:

 window.onload = function () { alert('Hello!') // it will not work!!! } window.onload = function () { alert('Bye!') }

This is because onload is just property of the object, which is overwritten.这是因为 onload 只是对象的属性,它被覆盖了。

By analogy with addEventListener , it is better to use $(document).ready() rather than onload.addEventListener类比,最好使用$(document).ready()而不是 onload。

 $(document).ready(function() { // Executes when the HTML document is loaded and the DOM is ready alert("Document is ready"); }); // .load() method deprecated from jQuery 1.8 onward $(window).on("load", function() { // Executes when complete page is fully loaded, including // all frames, objects and images alert("Window is loaded"); });
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

A word of caution on using $(document).ready() with Internet Explorer.在 Internet Explorer 中使用$(document).ready()的注意事项。 If an HTTP request is interrupted before the entire document is loaded (for example, while a page is streaming to the browser, another link is clicked) IE will trigger the $(document).ready event.如果加载整个文档之前HTTP 请求被中断(例如,当页面流式传输到浏览器时,单击了另一个链接)IE 将触发$(document).ready事件。

If any code within the $(document).ready() event references DOM objects, the potential exists for those objects to be not found, and Javascript errors can occur.如果$(document).ready()事件中的任何代码引用了 DOM 对象,则存在找不到这些对象的可能性,并且可能会发生 Javascript 错误。 Either guard your references to those objects, or defer code which references those objects to the window.load event.要么保护您对这些对象的引用,要么将引用这些对象的代码推迟到 window.load 事件。

I have not been able to reproduce this problem in other browsers (specifically, Chrome and Firefox)我无法在其他浏览器(特别是 Chrome 和 Firefox)中重现此问题

The $(document).ready() is a jQuery event which occurs when the HTML document has been fully loaded, while the window.onload event occurs later, when everything including images on the page loaded. $(document).ready()是一个jQuery事件,它在 HTML 文档完全加载时发生,而window.onload事件稍后发生,当包括页面上的图像在内的所有内容加载时。

Also window.onload is a pure javascript event in the DOM, while the $(document).ready() event is a method in jQuery. window.onload 是 DOM 中的纯 javascript 事件,而$(document).ready()事件是 jQuery 中的方法。

$(document).ready() is usually the wrapper for jQuery to make sure the elements all loaded in to be used in jQuery... $(document).ready()通常是 jQuery 的包装器,以确保所有加载的元素都可以在 jQuery 中使用...

Look at to jQuery source code to understand how it's working:查看 jQuery 源代码以了解它是如何工作的:

jQuery.ready.promise = function( obj ) {
    if ( !readyList ) {

        readyList = jQuery.Deferred();

        // Catch cases where $(document).ready() is called after the browser event has already occurred.
        // we once tried to use readyState "interactive" here, but it caused issues like the one
        // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
        if ( document.readyState === "complete" ) {
            // Handle it asynchronously to allow scripts the opportunity to delay ready
            setTimeout( jQuery.ready );

        // Standards-based browsers support DOMContentLoaded
        } else if ( document.addEventListener ) {
            // Use the handy event callback
            document.addEventListener( "DOMContentLoaded", completed, false );

            // A fallback to window.onload, that will always work
            window.addEventListener( "load", completed, false );

        // If IE event model is used
        } else {
            // Ensure firing before onload, maybe late but safe also for iframes
            document.attachEvent( "onreadystatechange", completed );

            // A fallback to window.onload, that will always work
            window.attachEvent( "onload", completed );

            // If IE and not a frame
            // continually check to see if the document is ready
            var top = false;

            try {
                top = window.frameElement == null && document.documentElement;
            } catch(e) {}

            if ( top && top.doScroll ) {
                (function doScrollCheck() {
                    if ( !jQuery.isReady ) {

                        try {
                            // Use the trick by Diego Perini
                            // http://javascript.nwbox.com/IEContentLoaded/
                            top.doScroll("left");
                        } catch(e) {
                            return setTimeout( doScrollCheck, 50 );
                        }

                        // detach all dom ready events
                        detach();

                        // and execute any waiting functions
                        jQuery.ready();
                    }
                })();
            }
        }
    }
    return readyList.promise( obj );
};
jQuery.fn.ready = function( fn ) {
    // Add the callback
    jQuery.ready.promise().done( fn );

    return this;
};

Also I have created the image below as a quick references for both:我还创建了下面的图像作为两者的快速参考:

在此处输入图片说明

Events活动

$(document).on('ready', handler) binds to the ready event from jQuery. $(document).on('ready', handler)从 jQuery 绑定到 ready 事件。 The handler is called when the DOM is loaded .加载 DOM 时调用处理程序。 Assets like images maybe still are missing .图像这样的资产可能仍然缺失 It will never be called if the document is ready at the time of binding.如果文档在绑定时准备好,它将永远不会被调用。 jQuery uses the DOMContentLoaded -Event for that, emulating it if not available. jQuery 为此使用DOMContentLoaded -Event,如果不可用则模拟它。

$(document).on('load', handler) is an event that will be fired once all resources are loaded from the server. $(document).on('load', handler)是一个事件,一旦从服务器加载了所有资源,就会触发该事件。 Images are loaded now.现在加载图像。 While onload is a raw HTML event, ready is built by jQuery. onload是一个原始的 HTML 事件,而ready是由 jQuery 构建的。

Functions功能

$(document).ready(handler) actually is a promise . $(document).ready(handler)实际上是一个promise The handler will be called immediately if document is ready at the time of calling.如果在调用时文档已准备好,将立即调用处理程序。 Otherwise it binds to the ready -Event.否则它绑定到ready -Event。

Before jQuery 1.8 , $(document).load(handler) existed as an alias to $(document).on('load',handler) .在 jQuery 1.8 之前$(document).load(handler)作为$(document).on('load',handler)的别名存在。

Further Reading进一步阅读

window.onload: A normal JavaScript event. window.onload:一个普通的 JavaScript 事件。

document.ready: A specific jQuery event when the entire HTML has been loaded. document.ready:加载整个 HTML 时的特定 jQuery 事件。

Document.ready (a jQuery event) will fire when all the elements are in place, and they can be referenced in the JavaScript code, but the content is not necessarily loaded. Document.ready (一个 jQuery 事件)将在所有元素都到位时触发,并且它们可以在 JavaScript 代码中被引用,但内容不一定加载。 Document.ready executes when the HTML document is loaded. Document.ready在加载 HTML 文档时执行。

$(document).ready(function() {

    // Code to be executed
    alert("Document is ready");
});

The window.load however will wait for the page to be fully loaded.然而window.load将等待页面完全加载。 This includes inner frames, images, etc.这包括内部框架、图像等。

$(window).load(function() {

    //Fires when the page is loaded completely
    alert("window is loaded");
});

One thing to remember (or should I say recall) is that you cannot stack onload s like you can with ready .要记住的一件事(或者我应该说是回忆)是您不能像使用ready那样堆叠onload In other words, jQuery magic allows multiple ready s on the same page, but you can't do that with onload .换句话说,jQuery 的魔法允许在同一个页面上有多个ready ,但是你不能用onload做到这一点。

The last onload will overrule any previous onload s.最后的onload将否决任何先前的onload

A nice way to deal with that is with a function apparently written by one Simon Willison and described in Using Multiple JavaScript Onload Functions .一个很好的处理方法是使用一个显然由 Simon Willison 编写并在Using Multiple JavaScript Onload Functions 中描述的函数

function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = func;
    }
    else {
        window.onload = function() {
            if (oldonload) {
                oldonload();
            }
            func();
        }
    }
}

// Example use:
addLoadEvent(nameOfSomeFunctionToRunOnPageLoad);
addLoadEvent(function() {
  /* More code to run on page load */
});

The document.ready event occurs when the HTML document has been loaded, and the window.onload event occurs always later, when all content (images, etc) has been loaded. document.ready 事件在 HTML 文档加载完毕后发生,而window.onload事件总是在加载所有内容(图像等)后发生。

You can use the document.ready event if you want to intervene "early" in the rendering process, without waiting for the images to load.如果您想在渲染过程中“尽早”干预,而无需等待图像加载,则可以使用document.ready事件。 If you need the images (or any other "content") ready before your script "does something", you need to wait until window.onload .如果您需要在脚本“执行某些操作”之前准备好图像(或任何其他“内容”),则需要等到window.onload

For instance, if you are implementing a "Slide Show" pattern, and you need to perform calculations based on image sizes, you may want to wait until window.onload .例如,如果您正在实施“幻灯片放映”模式,并且您需要根据图像大小执行计算,您可能需要等到window.onload Otherwise, you might experience some random problems, depending on how fast the images will get loaded.否则,您可能会遇到一些随机问题,具体取决于图像加载的速度。 Your script would be running concurrently with the thread that loads images.您的脚本将与加载图像的线程同时运行。 If your script is long enough, or the server is fast enough, you may not notice a problem, if images happen to arrive in time.如果你的脚本足够长,或者服务器足够快,你可能不会注意到问题,如果图像恰好及时到达。 But the safest practice would be allowing for images to get loaded.但最安全的做法是允许加载图像。

document.ready could be a nice event for you to show some "loading..." sign to users, and upon window.onload , you can complete any scripting that needed resources loaded, and then finally remove the "Loading..." sign. document.ready可能是一个很好的事件,您可以向用户显示一些“正在加载...”标志,在window.onload ,您可以完成任何需要加载资源的脚本,然后最后删除“正在加载...”标志。

Examples :-例子:-

// document ready events
$(document).ready(function(){
     alert("document is ready..");
})

// using JQuery
$(function(){
   alert("document is ready..");
})

// window on load event
function myFunction(){
  alert("window is loaded..");
}
window.onload = myFunction;

window.onload is a JavaScript inbuilt function. window.onload是一个 JavaScript 内置函数。 window.onload trigger when the HTML page loaded. window.onload在 HTML 页面加载时触发。 window.onload can be written only once. window.onload只能写入一次。

document.ready is a function of the jQuery library. document.ready是 jQuery 库的一个函数。 document.ready triggers when HTML and all JavaScript code, CSS, and images which are included in the HTML file are completely loaded. document.ready在 HTML 和包含在 HTML 文件中的所有 JavaScript 代码、CSS 和图像完全加载时触发。 document.ready can be written multiple times according to requirements. document.ready可以根据需求多次写入。

When you say $(document).ready(f) , you tell script engine to do the following:当您说$(document).ready(f) ,您告诉脚本引擎执行以下操作:

  1. get the object document and push it, since it's not in local scope, it must do a hash table lookup to find where document is, fortunately document is globally bound so it is a single lookup.获取对象文档并推送它,因为它不在本地范围内,它必须进行哈希表查找以找到文档所在的位置,幸运的是文档是全局绑定的,因此它是单次查找。
  2. find the object $ and select it, since it's not in local scope, it must do a hash table lookup, which may or may not have collisions.找到对象$并选择它,因为它不在本地范围内,所以它必须进行哈希表查找,这可能会或可能不会发生冲突。
  3. find the object f in global scope, which is another hash table lookup, or push function object and initialize it.在全局范围内找到对象f,这是另一个哈希表查找,或者推送函数对象并初始化它。
  4. call ready of selected object, which involves another hash table lookup into the selected object to find the method and invoke it.调用选定对象的ready ,这涉及到选定对象的另一个哈希表查找以找到方法并调用它。
  5. done.完成。

In the best case, this is 2 hash table lookups, but that's ignoring the heavy work done by jQuery, where $ is the kitchen sink of all possible inputs to jQuery, so another map is likely there to dispatch the query to correct handler.在最好的情况下,这是 2 个哈希表查找,但这忽略了 jQuery 完成的繁重工作,其中$是 jQuery 的所有可能输入的厨房接收器,因此另一个映射可能会在那里将查询分派到正确的处理程序。

Alternatively, you could do this:或者,您可以这样做:

window.onload = function() {...}

which will这将

  1. find the object window in global scope, if the JavaScript is optimized, it will know that since window isn't changed, it has already the selected object, so nothing needs to be done.在全局范围内找到对象window,如果优化JavaScript,就会知道因为window没有改变,它已经被选中了,所以什么都不用做。
  2. function object is pushed on the operand stack.函数对象被压入操作数堆栈。
  3. check if onload is a property or not by doing a hash table lookup, since it is, it is called like a function.通过进行哈希表查找来检查onload是否是一个属性,因为它是一个属性,因此它像函数一样被调用。

In the best case, this costs a single hash table lookup, which is necessary because onload must be fetched.在最好的情况下,这会花费单个哈希表查找,这是必要的,因为必须获取onload

Ideally, jQuery would compile their queries to strings that can be pasted to do what you wanted jQuery to do but without the runtime dispatching of jQuery.理想情况下,jQuery 会将它们的查询编译为可以粘贴的字符串,以执行您希望 jQuery 执行的操作,但无需 jQuery 的运行时分派。 This way you have an option of either这样你就可以选择

  1. do dynamic dispatch of jquery like we do today.像我们今天所做的那样动态调度 jquery。
  2. have jQuery compile your query to pure JavaScript string that can be passed to eval to do what you want.让 jQuery 将您的查询编译为纯 JavaScript 字符串,该字符串可以传递给 eval 以执行您想要的操作。
  3. copy the result of 2 directly into your code, and skip the cost of eval .将 2 的结果直接复制到您的代码中,并跳过eval的成本。

window.onload is provided by DOM api and it says " the load event fires when a given resource has loaded". window.onload 由 DOM api 提供,它表示“加载给定资源时会触发加载事件”。

"The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading." “load 事件在文档加载过程结束时触发。此时,文档中的所有对象都在 DOM 中,所有图像、脚本、链接和子框架都已完成加载。” DOM onload DOM 加载

But in jQuery $(document).ready() will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute.但是在 jQuery 中,$(document).ready() 只会在页面文档对象模型 (DOM) 准备好执行 JavaScript 代码时运行。 This does not include images, scripts, iframes etc. jquery ready event这不包括图像、脚本、iframe 等jquery 就绪事件

So the jquery ready method will run earlier than the dom onload event.所以jquery ready方法会于dom onload事件运行。

Time flies, it's ECMAScript 2021 now and IE11 is used by people less and less.时光飞逝,现在是 ECMAScript 2021,IE11 的人越来越少。 The most two events in contrast are load and DOMContentLoaded .相比之下,最多的两个事件是loadDOMContentLoaded

DOMContentLoaded fires after the initial HTML document has been completely loaded and parsed . DOMContentLoaded初始HTML 文档完全加载和解析后触发。

load fires after DOMContentLoaded and the whole page has loaded, waiting for all dependent resources to finish loading . loadDOMContentLoaded和整个页面加载后触发,等待所有依赖资源完成加载 Example of resources: scripts, stylesheets, images and iframes etc.资源示例:脚本、样式表、图像和 iframe 等。

IMPORTANT: Synchronous scripts will pause parsing of the DOM.重要提示:同步脚本将暂停解析 DOM。

Both two events can be used to determine the DOM is able to use or not.这两个事件都可以用来判断 DOM 是否可以使用。 For examples:例如:

<script>
    // DOM hasn't been completely parsed
    document.body; // null

    document.addEventListener('DOMContentLoaded', () => {
        // Now safely manipulate DOM
        document.querySelector('#id');
        document.body.appendChild();
    });

    /**
     * Should be used only to detect a fully-loaded page.
     * 
     * If you just want to manipulate DOM safely, `DOMContentLoaded` is better.
     */
    window.addEventListener('load', () => {
        // Safely manipulate DOM too
        document.links;
    });
</script>

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

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