Javascript - Как определить, загружен ли документ (IE 7/Firefox 3)

Я хочу вызвать функцию после загрузки документа, но документ может или не закончил загрузку. Если он загрузился, я могу просто вызвать функцию. Если он НЕ загружается, я могу подключить прослушиватель событий. Я не могу добавить eventlistener после того, как onload уже запущен, так как он не будет вызван. Итак, как я могу проверить, загружен ли документ? Я попробовал код ниже, но он не работает полностью. Любые идеи?

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

Нет необходимости во всем коде, упомянутом 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 в Mozilla Developer Network

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

Ответ 2

Нет необходимости в библиотеке. jQuery некоторое время использовал этот script, 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

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

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

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

Казалось бы, вы делаете то, что вам нужно.

Ответ 4

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

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

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

Затем ваш код:

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

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

Там может быть лучший способ, но я еще не нашел его.

Ответ 5

if(document.readyState === 'complete') {
    DoStuffFunction();
} else {
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}

Ответ 6

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

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

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

}

Ответ 7

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

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

В DOMContentLoaded документ Mozila говорит:

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

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

Ответ 8

Попробуйте следующее:

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

У меня есть другое решение, мое приложение нужно запускать, когда создается новый объект 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');

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