使用jQuery,我们都知道很棒的.ready()函数:

$('document').ready(function(){});

然而,假设我想运行一个用标准JavaScript编写的函数,而没有库支持它,并且我想在页面准备好处理它后立即启动一个函数。正确的方法是什么?

我知道我能做到:

window.onload="myFunction()";

或者我可以使用body标签:

<body onload="myFunction()">

或者,我甚至可以在页面底部尝试所有内容,但结尾正文或html标记如下:

<script type="text/javascript">
    myFunction();
</script>

什么是以jQuery的$.ready()这样的方式发出一个或多个函数的跨浏览器(旧/新)兼容方法?


当前回答

准备好的

function ready(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();}

像这样使用

ready(function(){
    //some code
});

用于自调用代码

(function(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();})(function(){

    //Some Code here
    //DOM is avaliable
    //var h1s = document.querySelector("h1");

});

支持:IE9+

其他回答

这是Ramswaloop“适用于所有浏览器”的一个清理过的、非eval版本——适用于所有的浏览器!

function onReady(yourMethod) {
  var readyStateCheckInterval = setInterval(function() {
    if (document && document.readyState === 'complete') { // Or 'interactive'
      clearInterval(readyStateCheckInterval);
      yourMethod();
    }
  }, 10);
}
// use like
onReady(function() { alert('hello'); } );

然而,它确实需要额外等待10毫秒才能运行,所以这里有一个更复杂的方法不应该:

function onReady(yourMethod) {
  if (document.readyState === 'complete') { // Or also compare to 'interactive'
    setTimeout(yourMethod, 1); // Schedule to run immediately
  }
  else {
    readyStateCheckInterval = setInterval(function() {
      if (document.readyState === 'complete') { // Or also compare to 'interactive'
        clearInterval(readyStateCheckInterval);
        yourMethod();
      }
    }, 10);
  }
}

// Use like
onReady(function() { alert('hello'); } );

// Or
onReady(functionName);

另请参阅How to check if DOM is ready without a framework?。

在IE9、最新的Firefox和Chrome中测试,IE8也支持。

document.onreadystatechange = function () {
  var state = document.readyState;
  if (state == 'interactive') {
      init();
  } else if (state == 'complete') {
      initOnCompleteLoad();
  }
}​;

例子:http://jsfiddle.net/electricvisions/Jacck/

UPDATE-可重用版本

我刚刚开发了以下内容。它相当简单地等同于jQuery或Dom ready,没有向后兼容性。它可能需要进一步完善。在最新版本的Chrome、Firefox和IE(10/11)中进行了测试,应该可以在旧版浏览器中工作,如评论所述。如果发现任何问题,我将进行更新。

window.readyHandlers = [];
window.ready = function ready(handler) {
  window.readyHandlers.push(handler);
  handleState();
};

window.handleState = function handleState () {
  if (['interactive', 'complete'].indexOf(document.readyState) > -1) {
    while(window.readyHandlers.length > 0) {
      (window.readyHandlers.shift())();
    }
  }
};

document.onreadystatechange = window.handleState;

用法:

ready(function () {
  // your code here
});

它是为了处理JS的异步加载而编写的,但除非您正在缩小,否则您可能需要先同步加载此脚本。我发现它在开发中很有用。

现代浏览器还支持异步加载脚本,这进一步增强了体验。支持异步意味着可以在呈现页面的同时同时下载多个脚本。当依赖于异步加载的其他脚本或使用minifier或类似browserfy的东西来处理依赖项时,请注意。

我想在这里提到一些可能的方法,以及一个适用于所有浏览器的纯javascript技巧:

// with jQuery 
$(document).ready(function(){ /* ... */ });

// shorter jQuery version 
$(function(){ /* ... */ });

// without jQuery (doesn't work in older IEs)
document.addEventListener('DOMContentLoaded', function(){ 
    // your code goes here
}, false);

// and here's the trick (works everywhere)
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}
// use like
r(function(){
    alert('DOM Ready!');
});

正如原作者所解释的,这里的技巧是我们正在检查document.readyState属性。如果它包含字符串(如未初始化和加载时,前两个DOM就绪状态(共5个)),我们将设置超时并再次检查。否则,我们执行传递的函数。

这是jsFiddle的技巧,适用于所有浏览器。

感谢Tutorialzine将此内容纳入他们的书中。

我不太确定你在问什么,但也许这会有所帮助:

window.onload = function(){
    // Code. . .

}

Or:

window.onload = main;

function main(){
    // Code. . .

}

准备好的

function ready(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();}

像这样使用

ready(function(){
    //some code
});

用于自调用代码

(function(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();})(function(){

    //Some Code here
    //DOM is avaliable
    //var h1s = document.querySelector("h1");

});

支持:IE9+