2009-06-11 2 views
146

Я хочу вызвать функцию после того, как документ загрузится, но документ, возможно, еще не завершил загрузку. Если он загрузился, я могу просто вызвать функцию. Если он НЕ загружается, я могу подключить прослушиватель событий. Я не могу добавить eventlistener после того, как onload уже запущен, так как он не будет вызван. Итак, как я могу проверить, загружен ли документ? Я попробовал код ниже, но он не работает полностью. Есть идеи?Javascript - Как определить, загружен ли документ (IE 7/Firefox 3)

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); 
    } 
} 
+5

«Я хочу вызвать функцию после загрузки документа, но документ может или не закончил загрузку». Это не вычисляет. –

+4

Я считаю, что он не имеет контроля над тем, когда его блок кода изначально запускается, но хочет, чтобы DoStuffFunction() не вызывался до того, как документ закончил загрузку. –

+1

О, это имеет смысл. –

ответ

15

Возможно, вы захотите использовать что-то вроде jQuery, что упрощает программирование JS.

Что-то вроде:

$(document).ready(function(){ 
    // Your code here 
}); 

Казалось бы делать то, что вы после этого.

+2

И если он хочет увидеть, как jQuery делает это переносимым образом, источник jQuery находится там для проверки :-) –

+5

И если это не ясно, если 'ready()' вызывается * после загрузки документа, переданная функция запускается немедленно. –

+1

@Ben Blank: если, конечно, сам jQuery не включен после того, как документ загрузился;) –

5

Если вы действительно хотите, чтобы этот код работал на , загрузите, а не в domready (то есть, вам нужно, чтобы изображения также были загружены), то, к сожалению, функция готовности не делает это за вас. Я вообще просто сделать что-то вроде этого:

Включить в документ Javascript (т.е. всегда вызывается перед OnLoad уволен):

var pageisloaded=0; 
window.addEvent('load',function(){ 
pageisloaded=1; 
}); 

Тогда ваш код:

if (pageisloaded) { 
DoStuffFunction(); 
} else { 
window.addEvent('load',DoStuffFunction); 
} 

(Или эквивалент в рамках предпочтения.) Я использую этот код для прекционирования javascript и изображений для будущих страниц. Поскольку материал, который я получаю, вообще не используется для этой страницы, я не хочу, чтобы он имел преимущество перед быстрой загрузкой изображений.

Возможно, лучший способ, но я еще не нашел его.

31

Нет необходимости в библиотеке. jQuery использовал этот скрипт некоторое время, кстати.

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; 
+1

Именно то, что я искал - функция jQuery.ready без библиотеки jQuery. Thanx! – stricjux

+3

Полностью упустил точку вопроса. 'init' не будет запускаться, если этот код, который вы опубликовали, включен после того, как страница уже загружена, что является точкой OP: он/она не может контролировать, когда включен его сценарий. (обратите внимание, что будет работать только ветвь 'setInterval') –

+3

Это принадлежит к библиотеке. Наряду со всеми другими колесами люди обычно заново изобретают. – b01

5
if(document.loaded) { 
    DoStuffFunction(); 
} else { 
    if (window.addEventListener) { 
     window.addEventListener('load', DoStuffFunction, false); 
    } else { 
     window.attachEvent('onload', DoStuffFunction); 
    } 
} 
+0

Это хорошо работает! – Ankit

234

Там нет необходимости для всех код, указанный на galambalazs. Кросс-браузер способ сделать это в чистом JavaScript это просто тест document.readyState:

if (document.readyState === "complete") { init(); } 

Это также, как JQuery делает это.

В зависимости от того, где JavaScript загружается, это может быть сделано внутри интервала:

var readyStateCheckInterval = setInterval(function() { 
    if (document.readyState === "complete") { 
     clearInterval(readyStateCheckInterval); 
     init(); 
    } 
}, 10); 

В самом деле, document.readyState может иметь три состояния:

возвращает «загрузки», когда документ загружать, «интерактивно» после завершения разбора, но при этом загружать под-ресурсы и «завершать» после его загрузки. - document.readyState at Mozilla Developer Network

Так что, если вам нужно только DOM будет готов, проверьте document.readyState === "interactive".Если вам нужна вся страница, чтобы быть готовой, включая изображения, проверьте на document.readyState === "complete".

+0

Готово ли ReadyState загрузки изображений? – Costa

+3

@costa, если 'document.readyState ==" complete "', это означает, что все, включая изображения, были загружены. –

+0

Я использую комбинацию обоих событий и 'document.readyState', чтобы убедиться, что функция запускается после разбора DOM или позже, в зависимости от того, когда она была вызвана. Есть ли событие для * интерактивного * 'readyState'? –

3

Вышеупомянутый с JQuery является самым простым и в основном используемым способом. Однако вы можете использовать чистый javascript, но попытайтесь определить этот скрипт в голове, чтобы он читался в начале. То, что вы ищете, это window.onload event.

Ниже приведен простой сценарий, который я создал для запуска счетчика. Счетчик останавливается после 10 итераций

window.onload=function() 
{ 
    var counter = 0; 
    var interval1 = setInterval(function() 
    { 
     document.getElementById("div1").textContent=counter; 
     counter++; 
     if(counter==10) 
     { 
      clearInterval(interval1); 
     } 
    },1000); 

} 
1

У меня есть другое решение, нужно быть запущен мое приложение, когда новый объект MyApp создан, так он выглядит:

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'); 

он работает на всех браузеров, которые я знаю.

2

Попробуйте это:

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

Mozila Firefox говорит, что onreadystatechange является альтернативой DOMContentLoaded.

// alternative to DOMContentLoaded 
document.onreadystatechange = function() { 
    if (document.readyState == "complete") { 
     initApplication(); 
    } 
} 

В DOMContentLoaded док в Mozila говорит:

Событие DOMContentLoaded вызывается, когда документ был полностью загружен и разобран, не дожидаясь таблиц стилей, изображений, и подрамники для завершения загрузки (событие нагрузки может использоваться для обнаружения полностью загруженной страницы).

Я думаю, что load событие должно использоваться для полного документа + загрузка ресурсов.

Смежные вопросы