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

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


当前回答

对于IE9+:

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;
})();

我只使用:

setTimeout(function(){
    //reference/manipulate DOM here
});

而且与上面的答案中的document.addEventListener(“DOMContentLoaded”//等不同,它的工作时间可以追溯到IE9——http://caniuse.com/#search=DOMContentLoaded仅表示最近的IE11。

有趣的是,我在2009年偶然发现了这个setTimeout解决方案:检查DOM的准备是否过度?,我的意思是“使用各种框架的更复杂的方法来检查DOM的就绪性是否过分”。

我对这种技术为什么有效的最好解释是,当使用这样一个setTimeout的脚本到达时,DOM正处于解析过程中,因此setTimeout中的代码的执行会延迟到该操作完成。

使用纯JavaScript的最简单方法。没有jQuery:

document.addEventListener("DOMContentLoaded", function(event) {
   // Your code to run since DOM is loaded and ready
});

有一种基于标准的替代品DOMContentLoaded,99%以上的浏览器都支持它,但IE8:

document.addEventListener("DOMContentLoaded", function(event) { 
  //do work
});

jQuery的本机函数比window.onload复杂得多,如下所示。

function bindReady(){
    if ( readyBound ) return;
    readyBound = true;

    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", function(){
            document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
            jQuery.ready();
        }, false );

    // If IE event model is used
    } else if ( document.attachEvent ) {
        // ensure firing before onload,
        // maybe late but safe also for iframes
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", arguments.callee );
                jQuery.ready();
            }
        });

        // If IE and not an iframe
        // continually check to see if the document is ready
        if ( document.documentElement.doScroll && window == window.top ) (function(){
            if ( jQuery.isReady ) return;

            try {
                // If IE is used, use the trick by Diego Perini
                // http://javascript.nwbox.com/IEContentLoaded/
                document.documentElement.doScroll("left");
            } catch( error ) {
                setTimeout( arguments.callee, 0 );
                return;
            }

            // and execute any waiting functions
            jQuery.ready();
        })();
    }

    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready );
}

2022版本

2022年,您需要做的就是将defer属性放在脚本上,并将其加载到头部!

参考:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-推迟

<!doctype html>
<html>
<head>
  <script src="/script.js" defer></script>
</head>
<body>

 <p>In 2022, all you need to do is put the defer attribute on your script, and load it in the head!</p>

</body>
</html>