$ (document). уже эквивалент без jQuery

У меня есть script, который использует $(document).ready, но он не использует ничего из jQuery. Я хотел бы осветлить его, удалив зависимость jQuery.

Как я могу реализовать свои собственные функции $(document).ready без использования jQuery? Я знаю, что использование window.onload не будет таким же, как window.onload запускается после загрузки всех изображений, кадров и т.д.

Ответ 1

Существует замена на основе стандартов DOMContentLoaded, которая поддерживается более чем 98% браузеров, хотя не IE8:

document.addEventListener("DOMContentLoaded", function(event) { 
  //do work
});

Функция jQuery native намного сложнее, чем просто window.onload, как показано ниже.

function bindReady(){
    if ( readyBound ) return;
    readyBound = true;

    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", function(){
            document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
            jQuery.ready();
        }, false );

    // If IE event model is used
    } else if ( document.attachEvent ) {
        // ensure firing before onload,
        // maybe late but safe also for iframes
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", arguments.callee );
                jQuery.ready();
            }
        });

        // If IE and not an iframe
        // continually check to see if the document is ready
        if ( document.documentElement.doScroll && window == window.top ) (function(){
            if ( jQuery.isReady ) return;

            try {
                // If IE is used, use the trick by Diego Perini
                // http://javascript.nwbox.com/IEContentLoaded/
                document.documentElement.doScroll("left");
            } catch( error ) {
                setTimeout( arguments.callee, 0 );
                return;
            }

            // and execute any waiting functions
            jQuery.ready();
        })();
    }

    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready );
}

Ответ 2

Редактировать:

Вот жизнеспособная замена для JQuery готов

function ready(callback){
    // in case the document is already rendered
    if (document.readyState!='loading') callback();
    // modern browsers
    else if (document.addEventListener) document.addEventListener('DOMContentLoaded', callback);
    // IE <= 8
    else document.attachEvent('onreadystatechange', function(){
        if (document.readyState=='complete') callback();
    });
}

ready(function(){
    // do something
});

Взято с https://plainjs.com/javascript/events/running-code-when-the-document-is-ready-15/

Еще одна хорошая функция domReady, взята с fooobar.com/questions/2793/...


Поскольку принятый ответ был очень далек от завершения, я jQuery.ready() "готовую" функцию, такую как jQuery.ready() основанную на источнике jQuery 1.6.2:

var ready = (function(){

    var readyList,
        DOMContentLoaded,
        class2type = {};
        class2type["[object Boolean]"] = "boolean";
        class2type["[object Number]"] = "number";
        class2type["[object String]"] = "string";
        class2type["[object Function]"] = "function";
        class2type["[object Array]"] = "array";
        class2type["[object Date]"] = "date";
        class2type["[object RegExp]"] = "regexp";
        class2type["[object Object]"] = "object";

    var ReadyObj = {
        // Is the DOM ready to be used? Set to true once it occurs.
        isReady: false,
        // A counter to track how many items to wait for before
        // the ready event fires. See #6781
        readyWait: 1,
        // Hold (or release) the ready event
        holdReady: function( hold ) {
            if ( hold ) {
                ReadyObj.readyWait++;
            } else {
                ReadyObj.ready( true );
            }
        },
        // Handle when the DOM is ready
        ready: function( wait ) {
            // Either a released hold or an DOMready/load event and not yet ready
            if ( (wait === true && !--ReadyObj.readyWait) || (wait !== true && !ReadyObj.isReady) ) {
                // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
                if ( !document.body ) {
                    return setTimeout( ReadyObj.ready, 1 );
                }

                // Remember that the DOM is ready
                ReadyObj.isReady = true;
                // If a normal DOM Ready event fired, decrement, and wait if need be
                if ( wait !== true && --ReadyObj.readyWait > 0 ) {
                    return;
                }
                // If there are functions bound, to execute
                readyList.resolveWith( document, [ ReadyObj ] );

                // Trigger any bound ready events
                //if ( ReadyObj.fn.trigger ) {
                //    ReadyObj( document ).trigger( "ready" ).unbind( "ready" );
                //}
            }
        },
        bindReady: function() {
            if ( readyList ) {
                return;
            }
            readyList = ReadyObj._Deferred();

            // Catch cases where $(document).ready() is called after the
            // browser event has already occurred.
            if ( document.readyState === "complete" ) {
                // Handle it asynchronously to allow scripts the opportunity to delay ready
                return setTimeout( ReadyObj.ready, 1 );
            }

            // Mozilla, Opera and webkit nightlies currently support this event
            if ( document.addEventListener ) {
                // Use the handy event callback
                document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
                // A fallback to window.onload, that will always work
                window.addEventListener( "load", ReadyObj.ready, false );

            // If IE event model is used
            } else if ( document.attachEvent ) {
                // ensure firing before onload,
                // maybe late but safe also for iframes
                document.attachEvent( "onreadystatechange", DOMContentLoaded );

                // A fallback to window.onload, that will always work
                window.attachEvent( "onload", ReadyObj.ready );

                // If IE and not a frame
                // continually check to see if the document is ready
                var toplevel = false;

                try {
                    toplevel = window.frameElement == null;
                } catch(e) {}

                if ( document.documentElement.doScroll && toplevel ) {
                    doScrollCheck();
                }
            }
        },
        _Deferred: function() {
            var // callbacks list
                callbacks = [],
                // stored [ context , args ]
                fired,
                // to avoid firing when already doing so
                firing,
                // flag to know if the deferred has been cancelled
                cancelled,
                // the deferred itself
                deferred  = {

                    // done( f1, f2, ...)
                    done: function() {
                        if ( !cancelled ) {
                            var args = arguments,
                                i,
                                length,
                                elem,
                                type,
                                _fired;
                            if ( fired ) {
                                _fired = fired;
                                fired = 0;
                            }
                            for ( i = 0, length = args.length; i < length; i++ ) {
                                elem = args[ i ];
                                type = ReadyObj.type( elem );
                                if ( type === "array" ) {
                                    deferred.done.apply( deferred, elem );
                                } else if ( type === "function" ) {
                                    callbacks.push( elem );
                                }
                            }
                            if ( _fired ) {
                                deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
                            }
                        }
                        return this;
                    },

                    // resolve with given context and args
                    resolveWith: function( context, args ) {
                        if ( !cancelled && !fired && !firing ) {
                            // make sure args are available (#8421)
                            args = args || [];
                            firing = 1;
                            try {
                                while( callbacks[ 0 ] ) {
                                    callbacks.shift().apply( context, args );//shifts a callback, and applies it to document
                                }
                            }
                            finally {
                                fired = [ context, args ];
                                firing = 0;
                            }
                        }
                        return this;
                    },

                    // resolve with this as context and given arguments
                    resolve: function() {
                        deferred.resolveWith( this, arguments );
                        return this;
                    },

                    // Has this deferred been resolved?
                    isResolved: function() {
                        return !!( firing || fired );
                    },

                    // Cancel
                    cancel: function() {
                        cancelled = 1;
                        callbacks = [];
                        return this;
                    }
                };

            return deferred;
        },
        type: function( obj ) {
            return obj == null ?
                String( obj ) :
                class2type[ Object.prototype.toString.call(obj) ] || "object";
        }
    }
    // The DOM ready check for Internet Explorer
    function doScrollCheck() {
        if ( ReadyObj.isReady ) {
            return;
        }

        try {
            // If IE is used, use the trick by Diego Perini
            // http://javascript.nwbox.com/IEContentLoaded/
            document.documentElement.doScroll("left");
        } catch(e) {
            setTimeout( doScrollCheck, 1 );
            return;
        }

        // and execute any waiting functions
        ReadyObj.ready();
    }
    // Cleanup functions for the document ready method
    if ( document.addEventListener ) {
        DOMContentLoaded = function() {
            document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
            ReadyObj.ready();
        };

    } else if ( document.attachEvent ) {
        DOMContentLoaded = function() {
            // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", DOMContentLoaded );
                ReadyObj.ready();
            }
        };
    }
    function ready( fn ) {
        // Attach the listeners
        ReadyObj.bindReady();

        var type = ReadyObj.type( fn );

        // Add the callback
        readyList.done( fn );//readyList is result of _Deferred()
    }
    return ready;
})();

Как пользоваться:

<script>
    ready(function(){
        alert('It works!');
    });
    ready(function(){
        alert('Also works!');
    });
</script>

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

PS: предлагаю компилировать.

Или вы можете использовать http://dustindiaz.com/smallest-domready-ever:

function r(f){/in/.test(document.readyState)?setTimeout(r,9,f):f()}
r(function(){/*code to run*/});

или нативную функцию, если вам нужно только поддерживать новые браузеры (в отличие от готового jQuery, он не запустится, если вы добавите его после загрузки страницы)

document.addEventListener('DOMContentLoaded',function(){/*fun code to run*/})

Ответ 3

Три варианта:

  • Если script - последний тег тела, DOM будет готов до выполнения тега script
  • Когда DOM готов, "readyState" изменится на "complete"
  • Поместите все под прослушиватель событий "DOMContentLoaded"

onreadystatechange

  document.onreadystatechange = function () {
     if (document.readyState == "complete") {
     // document is ready. Do your stuff here
   }
 }

Источник: MDN

DOMContentLoaded

document.addEventListener('DOMContentLoaded', function() {
   console.log('document is ready. I can sleep now');
});

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

Ответ 4

Поместите свой <script>/*JavaScript code*/</script> вправо перед закрывающим тегом </body>.

По общему признанию, это может не устраивать все цели, поскольку для изменения файла HTML требуется просто изменить файл HTML, а не просто что-то сделать в файле JavaScript a la document.ready, но все же...

Ответ 5

Бедственное решение:

var checkLoad = function() {   
    document.readyState !== "complete" ? setTimeout(checkLoad, 11) : alert("loaded!");   
};  

checkLoad();  

Просмотр скрипта

Добавлено это, немного лучше, я думаю, собственный объем и не рекурсивный

(function(){
    var tId = setInterval(function() {
        if (document.readyState == "complete") onComplete()
    }, 11);
    function onComplete(){
        clearInterval(tId);    
        alert("loaded!");    
    };
})()

View Fiddle

Ответ 6

Я использую это:

document.addEventListener("DOMContentLoaded", function(event) { 
    //Do work
});

Примечание. Вероятно, это работает только с более новыми браузерами, особенно такими: http://caniuse.com/#feat=domcontentloaded

Ответ 7

Действительно, если вас беспокоит Internet 9+, этого кода было бы достаточно, чтобы заменить jQuery.ready:

    document.addEventListener("DOMContentLoaded", callback);

Если вы беспокоитесь о Internet Explorer 6 и некоторых действительно странных и редких браузерах, это будет работать:

domReady: function (callback) {
    // Mozilla, Opera and WebKit
    if (document.addEventListener) {
        document.addEventListener("DOMContentLoaded", callback, false);
        // If Internet Explorer, the event model is used
    } else if (document.attachEvent) {
        document.attachEvent("onreadystatechange", function() {
            if (document.readyState === "complete" ) {
                callback();
            }
        });
        // A fallback to window.onload, that will always work
    } else {
        var oldOnload = window.onload;
        window.onload = function () {
            oldOnload && oldOnload();
            callback();
        }
    }
},

Ответ 8

Этот вопрос задавался довольно давно. Для любого, кто только видит этот вопрос, теперь есть сайт под названием "вам может не понадобиться jquery" , который разбивается - по уровню поддержки IE требуется - все функции jquery и предоставляет некоторые альтернативные, более мелкие библиотеки.

Документ IE8 готов script в соответствии с вам может не понадобиться jquery

function ready(fn) {
    if (document.readyState != 'loading')
        fn();
    else if (document.addEventListener)
        document.addEventListener('DOMContentLoaded', fn);
    else
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState != 'loading')
                fn();
        });
}

Ответ 9

Недавно я использовал это для мобильного сайта. Это упрощенная версия John Resig от "Pro JavaScript Techniques". Это зависит от addEvent.

var ready = ( function () {
  function ready( f ) {
    if( ready.done ) return f();

    if( ready.timer ) {
      ready.ready.push(f);
    } else {
      addEvent( window, "load", isDOMReady );
      ready.ready = [ f ];
      ready.timer = setInterval(isDOMReady, 13);
    }
  };

  function isDOMReady() {
    if( ready.done ) return false;

    if( document && document.getElementsByTagName && document.getElementById && document.body ) {
      clearInterval( ready.timer );
      ready.timer = null;
      for( var i = 0; i < ready.ready.length; i++ ) {
        ready.ready[i]();
      }
      ready.ready = null;
      ready.done = true;
    }
  }

  return ready;
})();

Ответ 10

Ответ jQuery был очень полезен для меня. С небольшим количеством исправлений он хорошо меня удовлетворил. Надеюсь, это поможет кому-то еще.

function onReady ( callback ){
    var addListener = document.addEventListener || document.attachEvent,
        removeListener =  document.removeEventListener || document.detachEvent
        eventName = document.addEventListener ? "DOMContentLoaded" : "onreadystatechange"

    addListener.call(document, eventName, function(){
        removeListener( eventName, arguments.callee, false )
        callback()
    }, false )
}

Ответ 11

Кросс-браузер (тоже старые браузеры) и простое решение:

var docLoaded = setInterval(function () {
    if(document.readyState !== "complete") return;
    clearInterval(docLoaded);

    /*
        Your code goes here i.e. init()
    */
}, 30);

Отображение оповещения в jsfiddle

Ответ 12

Вот наименьший фрагмент кода для проверки готовности DOM, который работает во всех браузерах (даже IE 8):

r(function(){
    alert('DOM Ready!');
});
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}

Смотрите ответ.

Ответ 13

Просто добавьте это в нижнюю часть своей HTML-страницы...

<script>
    Your_Function();
</script>

Потому что HTML-документы анализируются верхним дном.

Ответ 14

Стоит посмотреть Rock Solid addEvent() и http://www.braksator.com/how-to-make-your-own-jquery.

Вот код, если сайт идет вниз

function addEvent(obj, type, fn) {
    if (obj.addEventListener) {
        obj.addEventListener(type, fn, false);
        EventCache.add(obj, type, fn);
    }
    else if (obj.attachEvent) {
        obj["e"+type+fn] = fn;
        obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
        obj.attachEvent( "on"+type, obj[type+fn] );
        EventCache.add(obj, type, fn);
    }
    else {
        obj["on"+type] = obj["e"+type+fn];
    }
}

var EventCache = function(){
    var listEvents = [];
    return {
        listEvents : listEvents,
        add : function(node, sEventName, fHandler){
            listEvents.push(arguments);
        },
        flush : function(){
            var i, item;
            for(i = listEvents.length - 1; i >= 0; i = i - 1){
                item = listEvents[i];
                if(item[0].removeEventListener){
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };
                if(item[1].substring(0, 2) != "on"){
                    item[1] = "on" + item[1];
                };
                if(item[0].detachEvent){
                    item[0].detachEvent(item[1], item[2]);
                };
                item[0][item[1]] = null;
            };
        }
    };
}();

// Usage
addEvent(window, 'unload', EventCache.flush);
addEvent(window, 'load', function(){alert("I'm ready");});

Ответ 15

Этот кросс-браузерный код вызовет функцию после готовности DOM:

var domReady=function(func){
    var scriptText='('+func+')();';
    var scriptElement=document.createElement('script');
    scriptElement.innerText=scriptText;
    document.body.appendChild(scriptElement);
};

Вот как это работает:

  • Первая строка domReady вызывает метод toString функции, чтобы получить строковое представление функции, которую вы передаете, и обертывает его в выражение, которое сразу вызывает функцию.
  • Остальная часть domReady создает элемент script с выражением и добавляет его в body документа.
  • Браузер запускает теги script, добавленные к body после готовности DOM.

Например, если вы выполните следующее: domReady(function(){alert();});, к элементу body добавится следующее:

 <script>(function (){alert();})();</script>

Обратите внимание, что это работает только для пользовательских функций. Следующие действия не будут работать: domReady(alert);

Ответ 16

Как насчет этого решения?

// other onload attached earlier
window.onload=function() {
   alert('test');
};

tmpPreviousFunction=window.onload ? window.onload : null;

// our onload function
window.onload=function() {
   alert('another message');

   // execute previous one
   if (tmpPreviousFunction) tmpPreviousFunction();
};

Ответ 17

Всегда полезно использовать эквиваленты JavaScript по сравнению с jQuery. Одна из причин - это меньшее количество библиотек, которые зависят от них, и они намного быстрее, чем эквиваленты jQuery.

Одна фантастическая ссылка для эквивалентов jQuery http://youmightnotneedjquery.com/.

Что касается вашего вопроса, я взял приведенный ниже код из приведенной выше ссылки:) Только оговорка заключается в том, что он работает только с Internet Explorer 9 и более поздней версией.

function ready(fn) {
    if (document.readyState != 'loading') {
        fn();
    }
    else {
        document.addEventListener('DOMContentLoaded', fn);
    }
}

Ответ 18

Мы обнаружили, что наша операционная система имеет очень быструю и кропотливую перекрестную версию, которая может сделать трюк для большинства простых случаев с минимальной реализацией:

window.onReady = function onReady(fn){
    document.body ? fn() : setTimeout(function(){ onReady(fn);},50);
};

Ответ 19

Представленные здесь решения setTimeout/setInterval будут работать только в определенных обстоятельствах.

Проблема проявляется особенно в старых версиях Internet Explorer до 8.

Переменные, влияющие на успех этих решений setTimeout/setInterval:

1) dynamic or static HTML
2) cached or non cached requests
3) size of the complete HTML document
4) chunked or non chunked transfer encoding

исходный (собственный Javascript) код, разрешающий эту конкретную проблему, находится здесь:

https://github.com/dperini/ContentLoaded
http://javascript.nwbox.com/ContentLoaded (test)

это код, из которого команда jQuery построила свою реализацию.

Ответ 20

Вот что я использую, это быстро и охватывает все базы, которые я думаю; работает для всего, кроме IE < 9.

(() => { function fn() {
    // "On document ready" commands:
    console.log(document.readyState);
};  
  if (document.readyState != 'loading') {fn()}
  else {document.addEventListener('DOMContentLoaded', fn)}
})();

Кажется, что это все ломает:

  • срабатывает немедленно, если DOM уже готов (если DOM не "загружается", но "интерактивен" или "завершен" )
  • Если DOM по-прежнему загружается, он устанавливает прослушиватель событий, когда DOM доступен (интерактивный).

Событие DOMContentLoaded доступно в IE9 и во всем остальном, поэтому я лично считаю, что это нормально использовать. Перепишите объявление функции стрелки в обычную анонимную функцию, если вы не переписываете свой код с ES2015 на ES5.

Если вы хотите подождать, пока все активы будут загружены, все изображения будут отображаться и т.д., тогда вместо этого используйте window.onload.

Ответ 21

Если вам не нужно поддерживать очень старые браузеры, вот как это сделать, даже если ваш внешний script загружен атрибутом async:

HTMLDocument.prototype.ready = new Promise(function(resolve) {
   if(document.readyState != "loading")
      resolve();
   else
      document.addEventListener("DOMContentLoaded", function() {
         resolve();
      });
});

document.ready.then(function() {
   console.log("document.ready");
});

Ответ 22

Я просто использую:

setTimeout(function(){
    //reference/manipulate DOM here
});

И в отличие от document.addEventListener("DOMContentLoaded" //etc, как в самом верхнем ответе, он работает еще в IE9 - http://caniuse.com/#search=DOMContentLoaded указывает только как недавно как IE11.

Например, перейдите в https://netrenderer.com/index.php, выберите Internet Explorer 9 из раскрывающегося списка, введите https://dexygen.github.io/blog/oct-2017/jekyll/jekyll-categories/liquid-templates/2017/10/22/how-jekyll-builds-site-categories.html и нажмите "Render", и вы увидите что-то похожее на скриншот внизу этого сообщения.

См. следующий код Javascript, который я использую в заголовке, чтобы манипулировать стилем темы "Хакер" Jekyll по своему вкусу - в частности, вы можете ссылаться на блок if (location.pathname !== rootPath), чтобы увидеть, как я вставляю Home и Blog Home, которые отображаются IE9 на сайт NetRenderer.

Интересно, что я наткнулся на это решение setTimeout в 2009 году: Проверяет готовность переполнения DOM?, который, вероятно, мог быть сформулирован немного лучше, поскольку Я имел в виду использование более сложных подходов к различным инфраструктурам.

setTimeout(function() {//delay execution until after dom is parsed
    var containerEls = document.getElementsByClassName('container');
    var headingEl = containerEls[0].getElementsByTagName('h1')[0];
    var headerEl = document.getElementsByTagName('header')[0];
    var downloadsSectionEl = document.getElementById('downloads');
    var rootPath = "/";
    var blogRootPath = "/blog/";

    containerEls[0].style.maxWidth = '800px';
    containerEls[1].style.maxWidth = '800px';
    headingEl.style.margin = '0';
    headerEl.style.marginBottom = '7px';
    downloadsSectionEl.style.margin = '0';

    if (location.pathname !== rootPath) {
        downloadsSectionEl.appendChild(generateNavLink('Home', rootPath));
        if (location.pathname !== blogRootPath) {
            downloadsSectionEl.appendChild(document.createTextNode(' | '));
            downloadsSectionEl.appendChild(generateNavLink('Blog Home', blogRootPath));
        }
    }

    function generateNavLink(linkText, hrefPath) {
        var navLink = document.createElement('a');
        var linkTextNode = document.createTextNode(linkText);
        navLink.setAttribute('href', hrefPath);
        navLink.appendChild(linkTextNode);
        return navLink;
    }
});

dexygen.github.io на IE9

Ответ 23

Готовая функция в jQuery делает несколько вещей. Честно говоря, я не вижу, чтобы это заменило его, если у вас не было удивительно небольшой выход с вашего сайта. jQuery - довольно маленькая библиотека, и она обрабатывает все виды кросс-браузера, которые вам понадобятся позже.

Во всяком случае, здесь мало смысла публиковать его, просто откройте jQuery и посмотрите на метод bindReady.

Он начинается с вызова либо document.addEventListener("DOMContentLoaded") либо document.attachEvent('onreadystatechange') зависимости от модели события и продолжается оттуда.

Ответ 24

Если вы загружаете jQuery в нижней части BODY, но возникают проблемы с кодом, который записывает jQuery (<func> ) или jQuery (document).ready(<func> ), проверьте jqShim в Github.

Вместо того, чтобы воссоздать свою собственную функцию готовности документа, она просто удерживает функции до тех пор, пока не будет доступна jQuery, а затем продолжит работу с jQuery, как ожидалось. Точка перемещения jQuery в нижней части тела - ускорить загрузку страницы, и вы все равно можете выполнить ее, вставив jqShim.min.js в начало вашего шаблона.

Я закончил тем, что написал этот код, чтобы переместить все сценарии в WordPress в нижний колонтитул, и именно этот код прокладки теперь находится прямо в заголовке.

Ответ 25

Для IE9 +:

function ready(fn) {
  if (document.readyState != 'loading'){
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

Ответ 26

Этот подход является самым коротким способом, о котором я могу думать.

Решение, основанное на событии DOMContentLoaded, работает только в том случае, если перед документом загружается script, тогда как предложенная здесь ленивая проверка гарантирует, что код выполняется всегда, даже в сценариях, загружаемых динамически позже, точно так же, как документ JQuery готов.

Этот код совместим со всеми браузерами (включая некоторые устаревшие, вплоть до IE6 и Safari для Windows).

(function ready() {
    if (!document.body) {setTimeout(ready, 50); return;}
    // Document is ready here
})();

Ответ 27

function onDocReady(fn){ 
    $d.readyState!=="loading" ? fn():document.addEventListener('DOMContentLoaded',fn);
}

function onWinLoad(fn){
    $d.readyState==="complete") ? fn(): window.addEventListener('load',fn);
} 

onDocReady обеспечивает обратный вызов, когда HTML dom готов к полному доступу/анализу/манипуляции.

onWinLoad обеспечивает обратный вызов, когда все загружено (изображения и т.д.),

  • Эти функции можно вызвать, когда захотите.
  • Поддерживает несколько "слушателей".
  • Будет работать в любом браузере.

Ответ 28

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

function ready(callback){
    if(typeof callback === "function"){
        document.addEventListener("DOMContentLoaded", callback);
        window.addEventListener("load", callback);
    }else{
        throw new Error("Sorry, I can not run this!");
    }
}
ready(function(){
    console.log("It worked!");
});

Ответ 29

Большинство ванильных функций JS Ready НЕ учитывают сценарий, в котором DOMContentLoaded обработчик DOMContentLoaded после того, как документ уже загружен. Это означает, что функция никогда не будет работать. Это может произойти, если вы ищете DOMContentLoaded в async внешнем скрипте (<script async src="file.js"></script>).

Приведенный ниже код проверяет наличие DOMContentLoaded только в том случае, если документ readyState еще не является interactive или complete.

var DOMReady = function(callback) {
  document.readyState === "interactive" || document.readyState === "complete" ? callback() : document.addEventListener("DOMContentLoaded", callback());
};
DOMReady(function() {
  //DOM ready!
});

Если вы хотите поддержать IE, а также:

var DOMReady = function(callback) {
    if (document.readyState === "interactive" || document.readyState === "complete") {
        callback();
    } else if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', callback());
    } else if (document.attachEvent) {
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState != 'loading') {
                callback();
            }
        });
    }
};

DOMReady(function() {
  // DOM ready!
});

Ответ 30

Самый минимальный и 100% работающий

Я выбрал ответ от PlainJS, и он отлично работает для меня. Он расширяет DOMContentLoaded, так что он может быть принят во всех браузерах.


Эта функция является эквивалентом метода jQuery $(document).ready():

document.addEventListener('DOMContentLoaded', function(){
    // do something
});

Однако, в отличие от jQuery, этот код будет правильно работать только в современных браузерах (IE> 8) и не будет работать в случае, если документ уже отображается на момент вставки этого скрипта (например, через Ajax). Поэтому нам нужно немного расширить это:

function run() {
    // do something
}

// in case the document is already rendered
if (document.readyState!='loading') run();
// modern browsers
else if (document.addEventListener) 
document.addEventListener('DOMContentLoaded', run);
// IE <= 8
else document.attachEvent('onreadystatechange', function(){
    if (document.readyState=='complete') run();
});

Это охватывает практически все возможности и является жизнеспособной заменой помощнику jQuery.