我有一个使用了$(document).ready
的脚本,但它没有使用jQuery的其他任何功能。 我想通过去除jQuery依赖来减轻它的负担。
我如何在不使用jQuery的情况下实现自己的$(document).ready
功能? 我知道使用window.onload
将不同,因为window.onload
会在所有图像、框架等都加载完成后触发。
我有一个使用了$(document).ready
的脚本,但它没有使用jQuery的其他任何功能。 我想通过去除jQuery依赖来减轻它的负担。
我如何在不使用jQuery的情况下实现自己的$(document).ready
功能? 我知道使用window.onload
将不同,因为window.onload
会在所有图像、框架等都加载完成后触发。
跨浏览器(包括旧版浏览器)且简单的解决方案:
var docLoaded = setInterval(function () {
if(document.readyState !== "complete") return;
clearInterval(docLoaded);
/*
Your code goes here i.e. init()
*/
}, 30);
最近我在为一个移动网站使用这段代码。这是约翰·雷西格从《Pro JavaScript Techniques》中简化的版本。它依赖于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;
})();
jQuery的答案对我非常有用。稍加修改后,它可以很好地满足我的需求。 希望它能对其他人有所帮助。
function onReady ( callback ){
var addListener = document.addEventListener || document.attachEvent,
removeListener = document.removeEventListener || document.detachEvent
eventName = document.addEventListener ? "DOMContentLoaded" : "onreadystatechange"
addListener.call(document, eventName, function(){
removeListener( eventName, arguments.callee, false )
callback()
}, false )
}
removeListener
需要使用 document
作为上下文进行调用,例如 removeListener.call(document, ...
。 - Ron这是一个能够在所有浏览器中工作(包括 IE 8)的用来测试DOM是否准备就绪的最小代码片段:
r(function(){
alert('DOM Ready!');
});
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}
请查看此答案。
<script>
Your_Function();
</script>
使用纯JavaScript的最简单方法。不需要jQuery:
document.addEventListener("DOMContentLoaded", function(event) {
// Your code to run since DOM is loaded and ready
});
我从 PlainJS 中选择了一个答案,对我来说它很好用。 它扩展了 DOMContentLoaded
以便于在所有浏览器中都可以接受。
此函数相当于jQuery的 $(document).ready()
方法:
document.addEventListener('DOMContentLoaded', function(){
// do something
});
然而,与jQuery相比,这段代码只能在现代浏览器中(IE > 8)正确运行,在文档在插入此脚本时已经被渲染的情况下(例如通过Ajax),它将无法正常工作。因此,我们需要稍微进行扩展:
function run() {
// do something
}
// in case the document is already rendered
if (document.readyState!='loading') run();
// modern browsers
else if (document.addEventListener)
document.addEventListener('DOMContentLoaded', run);
// IE <= 8
else document.attachEvent('onreadystatechange', function(){
if (document.readyState=='complete') run();
});
值得一看的是 Rock Solid addEvent() 和 http://www.braksator.com/how-to-make-your-own-jquery。
以下是代码,以防该网站失效。
function addEvent(obj, type, fn) {
if (obj.addEventListener) {
obj.addEventListener(type, fn, false);
EventCache.add(obj, type, fn);
}
else if (obj.attachEvent) {
obj["e"+type+fn] = fn;
obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
obj.attachEvent( "on"+type, obj[type+fn] );
EventCache.add(obj, type, fn);
}
else {
obj["on"+type] = obj["e"+type+fn];
}
}
var EventCache = function(){
var listEvents = [];
return {
listEvents : listEvents,
add : function(node, sEventName, fHandler){
listEvents.push(arguments);
},
flush : function(){
var i, item;
for(i = listEvents.length - 1; i >= 0; i = i - 1){
item = listEvents[i];
if(item[0].removeEventListener){
item[0].removeEventListener(item[1], item[2], item[3]);
};
if(item[1].substring(0, 2) != "on"){
item[1] = "on" + item[1];
};
if(item[0].detachEvent){
item[0].detachEvent(item[1], item[2]);
};
item[0][item[1]] = null;
};
}
};
}();
// Usage
addEvent(window, 'unload', EventCache.flush);
addEvent(window, 'load', function(){alert("I'm ready");});
与jQuery相比,使用JavaScript等价代码总是更好的选择。一个原因是减少依赖库的数量,并且它们比jQuery等价代码更快。
关于jQuery等价代码的一个绝妙参考是http://youmightnotneedjquery.com/。
至于你的问题,我从上面的链接中采用了以下代码 :) 唯一的注意事项是它只适用于Internet Explorer 9及更高版本。
function ready(fn) {
if (document.readyState != 'loading') {
fn();
}
else {
document.addEventListener('DOMContentLoaded', fn);
}
}
var domReady=function(func){
var scriptText='('+func+')();';
var scriptElement=document.createElement('script');
scriptElement.innerText=scriptText;
document.body.appendChild(scriptElement);
};
domReady
的第一行调用函数的 toString
方法,以获取您传递的函数的字符串表示形式,并将其包装在立即调用该函数的表达式中。domReady
的其余部分创建一个带有该表达式的脚本元素,并将其附加到文档的 body
中。body
的脚本标记。domReady(function(){alert();});
,则以下内容将附加到 body
元素: <script>(function (){alert();})();</script>
domReady(alert);
$(document).ready
,那么你可以通过在页面底部而不是顶部运行代码来轻松解决这个问题。 HTML5Boilerplate正是采用了这种方法。 - Blazemonger