Javascript - Как определить, загружен ли документ (IE 7 / Firefox 3) - PullRequest
154 голосов
/ 11 июня 2009

Я хочу вызвать функцию после загрузки документа, но документ может или, возможно, еще не завершил загрузку. Если он загрузился, то я могу просто вызвать функцию. Если он НЕ загружается, тогда я могу прикрепить прослушиватель событий. Я не могу добавить список событий после того, как 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);
    }
}

Ответы [ 9 ]

242 голосов
/ 17 августа 2011

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

32 голосов
/ 30 июня 2010

Нет необходимости в библиотеке. 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;
15 голосов
/ 11 июня 2009

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

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

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

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

5 голосов
/ 21 августа 2009

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

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

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

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

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

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

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

4 голосов
/ 17 ноября 2010
if(document.loaded) {
    DoStuffFunction();
} else {
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}
3 голосов
/ 16 июля 2014

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

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

В DOMContentLoaded документ Мозилы говорит:

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

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

3 голосов
/ 11 апреля 2012

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

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

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

}
2 голосов
/ 10 декабря 2013

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

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);
    }
}
1 голос
/ 05 июня 2013

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

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

...