我有一个使用$(document).ready的脚本,但它不使用jQuery中的任何其他内容。我想通过删除jQuery依赖项来减轻它。

如何在不使用jQuery的情况下实现我自己的$(document).ready功能?我知道,使用window.onload将不同,因为window.onlead在加载所有图像、帧等后启动。


当前回答

以下是测试DOM就绪的最小代码片段,它适用于所有浏览器(甚至IE 8):

r(function(){
    alert('DOM Ready!');
});
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}

看到这个答案。

其他回答

比较

这里(在下面的片段中)是所选择的可用浏览器“内置”方法及其执行顺序的比较。评论

任何现代浏览器都不支持document.onload(X)(从不触发事件)如果您使用<body onload=“bodyOnLoad()”>(F),同时使用window.onload(E),则只执行第一个(因为它会覆盖第二个)<body onload=“…”>(F)中给定的事件处理程序由附加的onload函数包装document.onreadystatechange(D)不覆盖document.addEventListener('readystatechange'…)(C)可能是因为类似XYZevent的方法独立于addEventListener队列(允许添加多个侦听器)。在执行这两个处理程序之间可能不会发生任何事情。所有脚本都在控制台中写入时间戳,但也可以访问div的脚本也在主体中写入时间标记(在脚本执行后单击“FullPage”链接查看)。解决方案readystatechange(C,D)由浏览器执行多次,但针对不同的文档状态:loading-文档正在加载(没有在代码段中激发)交互式-文档在DOMContentLoaded之前被解析和激发完成-加载文档和资源,在加载body/window之前激发

<html><head><脚本>//溶液Aconsole.log(`[timestamp:${Date.now()}]A:Head脚本`);//溶液Bdocument.addEventListener(“DOMContentLoaded”,()=>{print(`[时间戳:${Date.now()}]B:DOMContentLoaded`);});//溶液Cdocument.addEventListener('readystatechange',()=>{print(`[时间戳:${Date.now()}]C:就绪状态:${document.ReadyState}`);});//溶液Ddocument.onreadystatechange=s=>{print(`[时间戳:${Date.now()}]D:document.onrreadystatechange就绪状态:${document.ReadyState}`)};//解决方案E(从未执行)window.onload=()=>{print(`E:<body onload=“…”>覆盖此处理程序`);};//溶液F函数体OnLoad(){print(`[timestamp:${Date.now()}]F:<body onload='…'>`);infoAboutOnLoad();//其他信息}//溶液Xdocument.onload=()=>{print(“document.onlead从未启动”)};//助手函数打印(txt){console.log(txt);如果(mydiv)mydiv.innerHTML+=txt.replace('<','&lt;').replace('>','&gt;')+'<br>';}函数infoAboutOnLoad(){console.log(“window.onload(重写后):”,(“”+document.body.onload).replace(/\s+/g,“”));console.log(`body.onload==window.onload-->${document.body.onload==window.onload}`);}console.log(“window.onload(覆盖前):”,(“”+document.body.onload).replace(/\s+/g,“”));</script></head><body onload=“bodyOnLoad()”><div id=“mydiv”></div><!-- 此脚本必须位于<body>-->的底部<脚本>//溶液Gprint(`[timestamp:${Date.now()}]G:<body>底部脚本`);</script></body></html>

这个解决方案怎么样?

// other onload attached earlier
window.onload=function() {
   alert('test');
};

tmpPreviousFunction=window.onload ? window.onload : null;

// our onload function
window.onload=function() {
   alert('another message');

   // execute previous one
   if (tmpPreviousFunction) tmpPreviousFunction();
};

这个问题很久以前就被问过了。对于任何看到这个问题的人来说,现在有一个名为“您可能不需要jquery”的网站,它按所需的IE支持级别分解了jquery的所有功能,并提供了一些替代的、较小的库。

IE8文档就绪脚本,根据您可能不需要jquery

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

与jQuery相比,使用JavaScript等价物总是很好的。一个原因是依赖的库少了一个,而且它们比jQuery等同物快得多。

jQuery等价物的一个极好的参考是http://youmightnotneedjquery.com/.

就您的问题而言,我从上面的链接中获取了以下代码:)唯一需要注意的是,它仅适用于Internet Explorer 9及更高版本。

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

我最近在一个移动网站上使用这个。这是John Resig的简化版“Pro JavaScript技术”。它取决于addEvent。

var ready = ( function () {
  function ready( f ) {
    if( ready.done ) return f();

    if( ready.timer ) {
      ready.ready.push(f);
    } else {
      addEvent( window, "load", isDOMReady );
      ready.ready = [ f ];
      ready.timer = setInterval(isDOMReady, 13);
    }
  };

  function isDOMReady() {
    if( ready.done ) return false;

    if( document && document.getElementsByTagName && document.getElementById && document.body ) {
      clearInterval( ready.timer );
      ready.timer = null;
      for( var i = 0; i < ready.ready.length; i++ ) {
        ready.ready[i]();
      }
      ready.ready = null;
      ready.done = true;
    }
  }

  return ready;
})();