在 jQuery 中,ready
函数是一个非常重要的部分,它用于确保在文档完全加载和解析之后才执行特定的代码,这对于需要操作 DOM 元素的脚本来说尤其重要,因为如果脚本在 DOM 元素还未加载完成时运行,可能会导致错误或未定义的行为。
`ready` 函数的实现原理
在 jQuery 中,ready
函数主要通过以下几种方式来实现:
1、DOMContentLoaded 事件:这是现代浏览器支持的一个事件,当初始的 HTML 文档被完全加载和解析完成之后,会触发这个事件。
2、readyState 属性:这是一个较老的方法,通过检查document.readyState
的值来判断文档是否已经加载完成。
3、回调队列:在文档加载完成之前,所有传递给ready
函数的回调都会被存储在一个队列中,一旦文档加载完成,这些回调会被依次执行。
源码分析
以下是 jQuery 中ready
函数的简化版源码分析:
// jQuery ready function implementation jQuery.fn.ready = function(callback) { // If the document is already "ready" (fully loaded), execute the callback immediately if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) { window.setTimeout(callback); } else { // Otherwise, add the callback to the list of functions to be executed once the document is ready var done = false; var top = true; // The function to call when the document is ready var ready = function() { if (!done) { done = true; if (document.addEventListener) { document.removeEventListener("DOMContentLoaded", ready); } callback(); } }; // Add event listener for DOMContentLoaded if (document.addEventListener) { document.addEventListener("DOMContentLoaded", ready); } else { // For older browsers that do not support addEventListener document.attachEvent("onreadystatechange", function() { if (document.readyState === "interactive") { ready(); } }); } } return this; };
关键点解释
1、立即执行回调:如果文档已经完全加载(document.readyState === "complete"
),则直接使用window.setTimeout
来异步执行回调函数,这确保了回调函数在当前调用栈完成后执行。
2、事件监听:如果文档尚未加载完成,则根据浏览器的支持情况添加相应的事件监听器,对于支持addEventListener
的浏览器,监听DOMContentLoaded
事件;对于不支持addEventListener
的旧浏览器,监听onreadystatechange
事件。
3、回调队列:在文档加载完成时,通过ready
函数来执行所有等待执行的回调函数,这里使用了一个简单的布尔变量done
来确保每个回调只执行一次。
4、兼容性处理:为了兼容老旧的浏览器,代码中包含了对document.addEventListener
和document.attachEvent
的处理。
jQuery 的ready
函数通过结合现代和传统的事件处理方法,确保了在文档完全加载后安全地执行回调函数,这种设计不仅提高了代码的兼容性,还保证了执行顺序的正确性。