JavaScript уже готов? - PullRequest
       23

JavaScript уже готов?

51 голосов
/ 30 июля 2009

Я знаю, что могу использовать разные фреймворки, такие как prototype или jquery, чтобы прикрепить функцию к window.onload, но это не то, что я ищу.

Мне нужно что-то вроде .readyState, чтобы я мог сделать что-то вроде этого:

if(document.isReady){
  var id = document.getElem ...
}

Есть ли другой способ, кроме использования того, что делают фреймворки?

Ответы [ 10 ]

42 голосов
/ 13 июня 2011

Редактировать: Поскольку наступает 2018 год, я думаю, что безопасно слушать событие DOMContentLoaded.

function fireOnReady() { /* ... */ }
if (document.readyState === 'complete') {
    fireOnReady();
} else {
    document.addEventListener("DOMContentLoaded", fireOnReady);
}

Обратите внимание, что событие будет запускаться только один раз при загрузке вашей страницы! Если вам нужно поддерживать действительно старые браузеры, посмотрите на суперлегкий скрипт, который я собрал ниже.



Только для ознакомления:



jQuery имеет недокументированное свойство isReady, которое используется для определения того, сработало ли событие готовности DOM:

if($.isReady) {
    // DOM is ready
} else {
    // DOM is not yet ready
}

Я начал с 1.5.2, вернулся к 1.3.2, и собственность там. Хотя я и недокументирован, я бы сказал, что вы можете положиться на это свойство в будущих версиях jQuery. Редактировать: И год спустя - v1.7.2, они все еще используют $.isReady - все еще без документов, поэтому, пожалуйста, используйте на свой страх и риск. Будьте осторожны при обновлении.

Редактировать: v1.9, они все еще используют $.isReady - все еще без документов

Редактировать: v2.0, со всеми его "основными" изменениями, по-прежнему используется $.isReady - все еще без документов

Редактировать: v3.x все еще использует $.isReady - все еще без документов

Редактировать: Как указали несколько человек, вышеизложенное на самом деле не отвечает на вопрос. Итак, я только что создал мини-готовый фрагмент DOM , который был вдохновлен Dustin Diaz еще меньшим готовым фрагментом DOM . Дастин создал удобный способ проверки документа readyState с помощью чего-то похожего на это:

if( !/in/.test(document.readyState) ) {
    // document is ready
} else {
    // document is NOT ready
}

Причина, по которой это работает, заключается в том, что браузер имеет 3 состояния загрузки: «загрузка», «интерактивный» и «полный» (более старый WebKit также использовал «загружен», но вам не нужно беспокоиться об этом больше) . Вы заметите, что и «загрузка», и «интерактивный» содержат текст «в» ... поэтому, если строка «в» находится внутри document.readyState, то мы знаем, что мы еще не готовы.

32 голосов
/ 30 июля 2009

Хотя я обычно рекомендую избегать использования фреймворков без необходимости, я бы сказал, что использование одного из них в этом случае вполне нормально. Вот jQuery:

$(function () {
    // do stuff after DOM has loaded
});

Обратите внимание, что это НЕ то же самое, что и событие window.onload, поскольку onload выполняется первым после загрузки других ресурсов (изображений и т. Д.). Код, который я использовал в моем примере, будет выполнен после завершения загрузки DOM, то есть, когда доступна полная структура HTML (не обязательно, когда доступны изображения, CSS и т. д.)

Если вам нужна проверяемая переменная, вы можете установить ее в функцию ready:

var documentIsReady = false;
$(function () { documentIsReady = true; });

Конечно, вы можете найти даже более легкие библиотеки, чем jQuery, если все, что вам нужно, это проверить DOM-ready. Но используйте библиотеку в тех случаях, когда разные браузеры ведут себя по-разному (это один из таких случаев.)

Используя некоторый код из библиотеки DOMAssistant , создание собственной функции "DOM is ready" не должно быть слишком сложным:

var domLoaded = function (callback) {
    /* Internet Explorer */
    /*@cc_on
    @if (@_win32 || @_win64)
        document.write('<script id="ieScriptLoad" defer src="//:"><\/script>');
        document.getElementById('ieScriptLoad').onreadystatechange = function() {
            if (this.readyState == 'complete') {
                callback();
            }
        };
    @end @*/
    /* Mozilla, Chrome, Opera */
    if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', callback, false);
    }
    /* Safari, iCab, Konqueror */
    if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
        var DOMLoadTimer = setInterval(function () {
            if (/loaded|complete/i.test(document.readyState)) {
                callback();
                clearInterval(DOMLoadTimer);
            }
        }, 10);
    }
    /* Other web browsers */
    window.onload = callback;
};

Не проверено, но должно работать. Я упростил это из DOMAssistant, потому что DOMAssistant допускает несколько обратных вызовов и имеет проверку, чтобы убедиться, что вы не можете добавить одну и ту же функцию дважды и т. Д.

29 голосов
/ 04 февраля 2015

За 5 лет, прошедших с тех пор, как был задан этот вопрос, DOMContentLoaded стало универсально поддерживаемым событием, и вы можете просто использовать его.

document.addEventListener('DOMContentLoaded', function() {
    //.. do stuff ..
}, false);
10 голосов
/ 29 августа 2014
document.addEventListener("DOMContentLoaded", function(e){
    console.log("dom ready");//output to web browser console
});

для этого не требуется JQuery. Нет необходимости передавать 3-й параметр в DOMContentLoaded, так как это событие не имеет родителя для прохождения события. Также не нужно увлекаться тем, что говорят все остальные. Это скажет вам, когда DOM полностью загружен и готов к использованию. Я LOLed, когда я заметил lib помощника DOM. Эта библиотека абсолютно бесполезна.

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

addEventListener() - отличная функция для проверки любого события, включая состояние готовности DOM. При использовании «DOMContentLoaded» 3-й параметр в addEventListener() не требуется, так как у этого триггера нет родительского элемента для передачи события. В моем примере выше вы заметите, что второй параметр является анонимной функцией. Вы также можете передать имя функции во второй параметр.

document.addEventListener([(string)event trigger], [function],[(boolean)traverse DOM tree]);

Еще одним преимуществом использования этого по сравнению с JQuery является то, что оно не сломается при обновлении JQuery.

10 голосов
/ 31 октября 2011

Проверьте это демо от Microsoft. -> http://ie.microsoft.com/testdrive/HTML5/DOMContentLoaded/Default.html И вот суть кода, который позволяет вам запускать JS на DOM готов ...

(function () {
    function load2(){
        // put whatever you need to load on DOM ready in here
        document.getElementById("but3").addEventListener("click", doMore, false);
    }
    if (window.addEventListener) {
        window.addEventListener('DOMContentLoaded', load2, false);
    } else {
        window.attachEvent('onload', load2);
    }
} ());

Вот некоторые из источников javascript для демонстрации. http://ie.microsoft.com/testdrive/Includes/Script/ReturnAndShareControls.js

Хорошо работает. Хорошо !! .. в Google Chrome и IE 9.

8 голосов
/ 12 августа 2013

я обновил код библиотеки DOMAssistant он отлично работает со мной

var domReady = (function (){
  var arrDomReadyCallBacks = [] ;
  function excuteDomReadyCallBacks(){
       for (var i=0; i < arrDomReadyCallBacks.length; i++) {
         arrDomReadyCallBacks[i]();
       }
       arrDomReadyCallBacks = [] ;
  }

  return function (callback){
    arrDomReadyCallBacks.push(callback);
     /* Mozilla, Chrome, Opera */
      if (document.addEventListener ) {
          document.addEventListener('DOMContentLoaded', excuteDomReadyCallBacks, false);
      }
    /* Safari, iCab, Konqueror */
    if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
        browserTypeSet = true ;
        var DOMLoadTimer = setInterval(function () {
            if (/loaded|complete/i.test(document.readyState)) {
                //callback();
                excuteDomReadyCallBacks();
                clearInterval(DOMLoadTimer);
            }
        }, 10);
    }
    /* Other web browsers */

    window.onload = excuteDomReadyCallBacks;
}
})()
6 голосов
/ 30 июля 2009

jQuery не использует window.onload.

$(document).ready() ожидает загрузки DOM и может быть пройден (остальная часть содержимого может быть загружена или не загружена этой точкой).

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

3 голосов
/ 30 июля 2009

Это на самом деле одна из главных причин, по которой большинство людей используют фреймворки, такие как jQuery, потому что решение этой проблемы не является единообразным для всех браузеров.

1 голос
/ 30 июня 2012

Попробуйте это:
Ссылка: onDomReady на GitHub или источник ниже:

if(document.ondomready == undefined) {
    document.ondomready = {};
    document.ondomready = null;
} else {
    document.ondomready=document.ondomready;
}
var oldonload=document.onload;
var isLaunched = 0;
document.onload = function() {  
    if(oldonload !== null) {
        oldonload.call();
    }
};
document.addEventListener("DOMContentLoaded", function onDom(evt) {
    var olddomready = document.ondomready;
    if(olddomready !== null) {
        if(isLaunched == 0) {
            olddomready.call(evt);
            isLaunched == 1;
            //We now launched the mapped DOMContentLoaded Event
        } else {
            //We already launched DOMContentLoaded Event
        }
    }
}, false);

Я уже проверял это на Opera 11.x / 12.x. Еще не проверено на других. Дайте мне знать, если они это сделают.

Примечание: Я еще не загрузил хранилище, но скоро буду в свободное время.

0 голосов
/ 02 декабря 2014

Если вам нужны меньшие библиотеки, которые выполняют только определенные задачи, вы можете использовать библиотеки в microjs . Для решения данного вопроса можно использовать готовый метод DOMStatic libs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...