JavaScript等效于jQuery的$ .ready()

JavaScript等效于jQuery的$ .ready(),第1张

JavaScript等效于jQuery的$ .ready()

在没有为您提供所有跨浏览器兼容性的框架的情况下,最简单的 *** 作就是将调用代码放在正文末尾。它比

onload
处理程序执行起来更快,因为它仅等待DOM准备就绪,而不等待所有图像加载。而且,这适用于所有浏览器。

<!doctype html><html><head></head><body>Your HTML here<script>// self executing function here(function() {   // your page initialization pre here   // the DOM will be available here})();</script></body></html>

对于现代浏览器(来自IE9和更高版本以及任何版本的Chrome,Firefox或Safari),如果您希望能够实现类似jQuery的

$(document).ready()
方法,可以从任何地方调用(而不必担心调用脚本的位置),您可以只使用以下内容:

function docReady(fn) {    // see if DOM is already available    if (document.readyState === "complete" || document.readyState === "interactive") {        // call on next available tick        setTimeout(fn, 1);    } else {        document.addEventListener("DOMContentLoaded", fn);    }}

用法:

docReady(function() {    // DOM is loaded and ready for manipulation here});

如果您需要完全的跨浏览器兼容性(包括IE的旧版本)并且不想等待

window.onload
,那么您可能应该看看jQuery之类的框架如何实现其
$(document).ready()
方法。根据浏览器的功能,它相当复杂。

让您稍微了解一下jQuery的功能(无论放置script标记的位置都可以使用jQuery)。

如果支持,它将尝试标准:

document.addEventListener('DOMContentLoaded', fn, false);

后退到:

window.addEventListener('load', fn, false )

或对于较旧版本的IE,它使用:

document.attachEvent("onreadystatechange", fn);

后退到:

window.attachEvent("onload", fn);

而且,我不太了解IE代码路径中的一些变通办法,但看起来它与框架有关。


这是

.ready()
用普通javascript编写的jQuery的完全替代:

(function(funcName, baseObj) {    // The public function name defaults to window.docReady    // but you can pass in your own object and own function name and those will be used    // if you want to put them in a different namespace    funcName = funcName || "docReady";    baseObj = baseObj || window;    var readyList = [];    var readyFired = false;    var readyEventHandlersInstalled = false;    // call this when the document is ready    // this function protects itself against being called more than once    function ready() {        if (!readyFired) { // this must be set to true before we start calling callbacks readyFired = true; for (var i = 0; i < readyList.length; i++) {     // if a callback here happens to add new ready handlers,     // the docReady() function will see that it already fired     // and will schedule the callback to run right after     // this event loop finishes so all handlers will still execute     // in order and no new ones will be added to the readyList     // while we are processing the list     readyList[i].fn.call(window, readyList[i].ctx); } // allow any closures held by these functions to free readyList = [];        }    }    function readyStateChange() {        if ( document.readyState === "complete" ) { ready();        }    }    // This is the one public interface    // docReady(fn, context);    // the context argument is optional - if present, it will be passed    // as an argument to the callback    baseObj[funcName] = function(callback, context) {        if (typeof callback !== "function") { throw new TypeError("callback for docReady(fn) must be a function");        }        // if ready has already fired, then just schedule the callback        // to fire asynchronously, but right away        if (readyFired) { setTimeout(function() {callback(context);}, 1); return;        } else { // add the function and context to the list readyList.push({fn: callback, ctx: context});        }        // if document already ready to go, schedule the ready function to run        if (document.readyState === "complete") { setTimeout(ready, 1);        } else if (!readyEventHandlersInstalled) { // otherwise if we don't have event handlers installed, install them if (document.addEventListener) {     // first choice is DOMContentLoaded event     document.addEventListener("DOMContentLoaded", ready, false);     // backup is window load event     window.addEventListener("load", ready, false); } else {     // must be IE     document.attachEvent("onreadystatechange", readyStateChange);     window.attachEvent("onload", ready); } readyEventHandlersInstalled = true;        }    }})("docReady", window);

用法:

// pass a function referencedocReady(fn);// use an anonymous functiondocReady(function() {    // pre here});// pass a function reference and a context// the context will be passed to the function as the first argumentdocReady(fn, context);// use an anonymous function with a contextdocReady(function(context) {    // pre here that can use the context argument that was passed to docReady}, ctx);

已在以下位置进行了测试:

IE6 and upFirefox 3.6 and upChrome 14 and upSafari 5.1 and upOpera 11.6 and upMultiple iOS devicesMultiple Android devices

以下是其工作原理的摘要:

  1. 创建一个IIFE,以便我们可以使用非公共状态变量。
  2. 宣布公共职能
    docReady(fn, context)
  3. docReady(fn, context)
    被调用时,检查是否准备好处理程序已经被解雇。如果是这样,只需安排新添加的回调在此JS线程结束后立即触发
    setTimeout(fn, 1)
  4. 如果就绪处理程序尚未触发,则将此新回调添加到稍后要调用的回调列表中。
  5. 检查文档是否已经准备好。如果是这样,请执行所有就绪的处理程序。
  6. 如果我们尚未安装事件侦听器,但尚不知道文档准备就绪的时间,请立即安装它们。
  7. 如果
    document.addEventListener
    存在,则安装
    .addEventListener()
    用于
    "DOMContentLoaded"
    "load"
    事件的事件处理程序。为了安全起见,“负载”是备用事件,因此不需要。
  8. 如果
    document.addEventListener
    不存在,则使用
    .attachEvent()
    for
    "onreadystatechange"
    "onload"
    events 安装事件处理程序。
  9. 在这种情况
    onreadystatechange
    下,请检查,如果是
    document.readyState === "complete"
    ,则调用函数以激发所有就绪的处理程序。
  10. 在所有其他事件处理程序中,调用一个函数以激发所有就绪的处理程序。
  11. 在调用所有就绪处理程序的函数中,检查一个状态变量以查看是否已经解雇了。如果有,什么也不做。如果尚未调用,请遍历就绪函数数组,并按添加顺序调用每个函数。设置一个标志以指示所有这些都已被调用,因此它们绝不会被执行多次。
  12. 清除函数数组,以便可以释放它们可能正在使用的所有闭包。

docReady()
向其注册的处理程序保证按其注册顺序触发。

如果您

docReady(fn)
在文档准备就绪后调用,则将计划使用当前执行线程完成后立即执行回调
setTimeout(fn,1)
。这使调用代码始终可以认为它们是异步回调,即使稍后在当前JS线程完成并保留调用顺序时也将稍后调用。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4931168.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-13
下一篇 2022-11-13

发表评论

登录后才能评论

评论列表(0条)

保存