可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to call a function after a document loads, but the document may or may not have finished loading yet. If it did load, then I can just call the function. If it did NOT load, then I can attach an event listener. I can\'t add an eventlistener after onload has already fired since it won\'t get called. So how can I check if the document has loaded? I tried the code below but it doesn\'t entirely work. Any ideas?
var body = document.getElementsByTagName(\'BODY\')[0];
// CONDITION DOES NOT WORK
if (body && body.readyState == \'loaded\') {
DoStuffFunction();
} else {
// CODE BELOW WORKS
if (window.addEventListener) {
window.addEventListener(\'load\', DoStuffFunction, false);
} else {
window.attachEvent(\'onload\', DoStuffFunction);
}
}
回答1:
There\'s no need for all the code mentioned by galambalazs. The cross-browser way to do it in pure JavaScript is simply to test document.readyState
:
if (document.readyState === \"complete\") { init(); }
This is also how jQuery does it.
Depending on where the JavaScript is loaded, this can be done inside an interval:
var readyStateCheckInterval = setInterval(function() {
if (document.readyState === \"complete\") {
clearInterval(readyStateCheckInterval);
init();
}
}, 10);
In fact, document.readyState
can have three states:
Returns \"loading\" while the document is loading, \"interactive\" once it is finished parsing but still loading sub-resources, and \"complete\" once it has loaded.
-- document.readyState at Mozilla Developer Network
So if you only need the DOM to be ready, check for document.readyState === \"interactive\"
. If you need the whole page to be ready, including images, check for document.readyState === \"complete\"
.
回答2:
No need for a library. jQuery used this script for a while, btw.
http://dean.edwards.name/weblog/2006/06/again/
// Dean Edwards/Matthias Miller/John Resig
function init() {
// quit if this function has already been called
if (arguments.callee.done) return;
// flag this function so we don\'t do the same thing twice
arguments.callee.done = true;
// kill the timer
if (_timer) clearInterval(_timer);
// do stuff
};
/* for Mozilla/Opera9 */
if (document.addEventListener) {
document.addEventListener(\"DOMContentLoaded\", init, false);
}
/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
document.write(\"<script id=__ie_onload defer src=javascript:void(0)><\\/script>\");
var script = document.getElementById(\"__ie_onload\");
script.onreadystatechange = function() {
if (this.readyState == \"complete\") {
init(); // call the onload handler
}
};
/*@end @*/
/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
var _timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
init(); // call the onload handler
}
}, 10);
}
/* for other browsers */
window.onload = init;
回答3:
You probably want to use something like jQuery, which makes JS programming easier.
Something like:
$(document).ready(function(){
// Your code here
});
Would seem to do what you are after.
回答4:
If you actually want this code to run at load, not at domready (ie you need the images to be loaded as well), then unfortunately the ready function doesn\'t do it for you. I generally just do something like this:
Include in document javascript (ie always called before onload fired):
var pageisloaded=0;
window.addEvent(\'load\',function(){
pageisloaded=1;
});
Then your code:
if (pageisloaded) {
DoStuffFunction();
} else {
window.addEvent(\'load\',DoStuffFunction);
}
(Or the equivalent in your framework of preference.) I use this code to do precaching of javascript and images for future pages. Since the stuff I\'m getting isn\'t used for this page at all, I don\'t want it to take precedence over the speedy download of images.
There may be a better way, but I\'ve yet to find it.
回答5:
if(document.loaded) {
DoStuffFunction();
} else {
if (window.addEventListener) {
window.addEventListener(\'load\', DoStuffFunction, false);
} else {
window.attachEvent(\'onload\', DoStuffFunction);
}
}
回答6:
Mozila Firefox says that onreadystatechange
is an alternative to DOMContentLoaded
.
// alternative to DOMContentLoaded
document.onreadystatechange = function () {
if (document.readyState == \"complete\") {
initApplication();
}
}
In DOMContentLoaded
the Mozila\'s doc says:
The DOMContentLoaded event is fired when the document has been
completely loaded and parsed, without waiting for stylesheets, images,
and subframes to finish loading (the load event can be used to detect
a fully-loaded page).
I think load
event should be used for a full document+resources loading.
回答7:
The above one with JQuery is the easiest and mostly used way. However you can use pure javascript but try to define this script in the head so that it is read at the beginning. What you are looking for is window.onload
event.
Below is a simple script that I created to run a counter. The counter then stops after 10 iterations
window.onload=function()
{
var counter = 0;
var interval1 = setInterval(function()
{
document.getElementById(\"div1\").textContent=counter;
counter++;
if(counter==10)
{
clearInterval(interval1);
}
},1000);
}
回答8:
Try this:
var body = document.getElementsByTagName(\'BODY\')[0];
// CONDITION DOES NOT WORK
if ((body && body.readyState == \'loaded\') || (body && body.readyState == \'complete\') ) {
DoStuffFunction();
} else {
// CODE BELOW WORKS
if (window.addEventListener) {
window.addEventListener(\'load\', DoStuffFunction, false);
} else {
window.attachEvent(\'onload\',DoStuffFunction);
}
}
回答9:
I have other solution, my application need to be started when new object of MyApp is created, so it looks like:
function MyApp(objId){
this.init=function(){
//.........
}
this.run=function(){
if(!document || !document.body || !window[objId]){
window.setTimeout(objId+\".run();\",100);
return;
}
this.init();
};
this.run();
}
//and i am starting it
var app=new MyApp(\'app\');
it is working on all browsers, that i know.