我有一个使用的脚本$(document).ready
,但没有使用jQuery中的其他任何脚本。我想通过删除jQuery依赖项来减轻它的负担。
如何在$(document).ready
不使用jQuery的情况下实现自己的功能?我知道使用window.onload
会有所不同,因为window.onload
在加载所有图像,帧等之后会触发。
我有一个使用的脚本$(document).ready
,但没有使用jQuery中的其他任何脚本。我想通过删除jQuery依赖项来减轻它的负担。
如何在$(document).ready
不使用jQuery的情况下实现自己的功能?我知道使用window.onload
会有所不同,因为window.onload
在加载所有图像,帧等之后会触发。
尝试这个:
function ready(callback){
if(typeof callback === "function"){
document.addEventListener("DOMContentLoaded", callback);
window.addEventListener("load", callback);
}else{
throw new Error("Sorry, I can not run this!");
}
}
ready(function(){
console.log("It worked!");
});
如果您不必支持非常老的浏览器,即使您的外部脚本加载了async属性,也可以使用以下方法:
HTMLDocument.prototype.ready = new Promise(function(resolve) {
if(document.readyState != "loading")
resolve();
else
document.addEventListener("DOMContentLoaded", function() {
resolve();
});
});
document.ready.then(function() {
console.log("document.ready");
});
我们发现我们的快速跨浏览器实现可以在最简单的情况下以最少的实现实现成功:
window.onReady = function onReady(fn){
document.body ? fn() : setTimeout(function(){ onReady(fn);},50);
};
这里介绍的setTimeout / setInterval解决方案仅在特定情况下有效。
尤其是在Internet Explorer 8以前的版本中,尤其是在出现此问题时。
影响这些setTimeout / setInterval解决方案成功的变量是:
1) dynamic or static HTML
2) cached or non cached requests
3) size of the complete HTML document
4) chunked or non chunked transfer encoding
解决此特定问题的原始(本地Javascript)代码如下:
https://github.com/dperini/ContentLoaded
http://javascript.nwbox.com/ContentLoaded (test)
这是jQuery团队用来构建其实现的代码。
只需将其添加到HTML页面的底部...
<script>
Your_Function();
</script>
因为,HTML文档是由上至下解析的。
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 )
}
我最近在移动网站上使用了它。这是John Resig的“ 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;
})();
跨浏览器(也是旧的浏览器)和一个简单的解决方案:
var docLoaded = setInterval(function () {
if(document.readyState !== "complete") return;
clearInterval(docLoaded);
/*
Your code goes here i.e. init()
*/
}, 30);
穷人的解决方案:
var checkLoad = function() {
document.readyState !== "complete" ? setTimeout(checkLoad, 11) : alert("loaded!");
};
checkLoad();
添加了这一点,我想更好一点,自己的范围,并且非递归
(function(){
var tId = setInterval(function() {
if (document.readyState == "complete") onComplete()
}, 11);
function onComplete(){
clearInterval(tId);
alert("loaded!");
};
})()
我用这个:
document.addEventListener("DOMContentLoaded", function(event) {
//Do work
});
注意:这可能仅适用于较新的浏览器,尤其是以下浏览器:http : //caniuse.com/#feat=domcontentloaded
确实,如果仅关心Internet Explorer 9+,那么此代码足以替换jQuery.ready
:
document.addEventListener("DOMContentLoaded", callback);
如果您担心Internet Explorer 6和某些真正奇怪且稀有的浏览器,则可以使用:
domReady: function (callback) {
// Mozilla, Opera and WebKit
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", callback, false);
// If Internet Explorer, the event model is used
} else if (document.attachEvent) {
document.attachEvent("onreadystatechange", function() {
if (document.readyState === "complete" ) {
callback();
}
});
// A fallback to window.onload, that will always work
} else {
var oldOnload = window.onload;
window.onload = function () {
oldOnload && oldOnload();
callback();
}
}
},
将您的<script>/*JavaScript code*/</script>
权利放在结束 </body>
标记之前。
诚然,这可能不适合每个人的目的,因为它需要更改HTML文件,而不是仅在JavaScript文件中做一些事情document.ready
,但是仍然...
有一个基于标准的替代品,尽管IE8不DOMContentLoaded
支持,但超过98%的浏览器都支持它:
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 );
}