Czysty odpowiednik JavaScript jQuery ' s $.ready () - jak wywołać funkcję, gdy strona / DOM jest na nią gotowa [duplikat]

to pytanie ma już odpowiedzi tutaj : $(dokument).gotowy odpowiednik bez jQuery (39 odpowiedzi) Zamknięty 4 lata temu.

Z jQuery wszyscy znamy cudowną .ready() funkcję:

$('document').ready(function(){});

Załóżmy jednak, że chcę uruchomić funkcję, która jest napisana w standardowym JavaScript, bez wsparcia biblioteki, i że chcę uruchomić funkcję, jak tylko strona będzie gotowa do obsługi. Jak to zrobić?

Wiem, że potrafię:

window.onload="myFunction()";

Lub mogę użyć tagu body:

<body onload="myFunction()">

Lub mogę nawet spróbować na dole strony po wszystkim, ale koniec body lub html tag jak:

<script type="text/javascript">
    myFunction();
</script>

Co to jest cross-browser (stara/Nowa)-zgodna metoda wydawania jednej lub więcej funkcji w sposób podobny do jQuery $.ready()?

Author: ΛRYΛN, 2012-03-27

10 answers

Najprostszą rzeczą do zrobienia w przypadku braku frameworka, który robi wszystkie kompatybilność między przeglądarkami dla Ciebie jest po prostu umieścić wywołanie do kodu na końcu ciała. Jest to szybsze do wykonania niż Obsługa onload, ponieważ czeka tylko na to, aby DOM był gotowy, a nie na załadowanie wszystkich obrazów. I to działa w każdej przeglądarce.

<!doctype html>
<html>
<head>
</head>
<body>
Your HTML here

<script>
// self executing function here
(function() {
   // your page initialization code here
   // the DOM will be available here

})();
</script>
</body>
</html>

Dla nowoczesnych przeglądarek (wszystko od IE9 i nowszych oraz dowolnej wersji Chrome, Firefox lub Safari), jeśli chcesz być w stanie zaimplementować metoda jQuery like $(document).ready(), którą możesz wywołać z dowolnego miejsca (nie martwiąc się o to, gdzie znajduje się skrypt wywołujący), możesz użyć czegoś takiego:

function docReady(fn) {
    // see if DOM is already available
    if (document.readyState === "complete" || document.readyState === "interactive") {
        // call on next available tick
        setTimeout(fn, 1);
    } else {
        document.addEventListener("DOMContentLoaded", fn);
    }
}    

Użycie:

docReady(function() {
    // DOM is loaded and ready for manipulation here
});

Jeśli potrzebujesz pełnej kompatybilności między przeglądarkami (włącznie ze starymi wersjami IE) i nie chcesz czekać na window.onload, prawdopodobnie powinieneś sprawdzić, jak framework taki jak jQuery implementuje swoją metodę $(document).ready(). Jest dość zaangażowany w zależności od możliwości przeglądarka.

Aby dać ci trochę pojęcia, co robi jQuery (które będzie działać wszędzie tam, gdzie tag skryptu jest umieszczony).

Jeśli jest obsługiwany, próbuje standardu:

document.addEventListener('DOMContentLoaded', fn, false);

Z powrotem do:

window.addEventListener('load', fn, false )

Lub dla starszych wersji IE używa:

document.attachEvent("onreadystatechange", fn);

Z powrotem do:

window.attachEvent("onload", fn);

W ścieżce kodu IE są pewne obejścia, których nie do końca podążam, ale wygląda na to, że ma to coś wspólnego z ramkami.


Oto pełna zamiast jQuery ' s .ready() napisany w prostym javascript:

(function(funcName, baseObj) {
    // The public function name defaults to window.docReady
    // but you can pass in your own object and own function name and those will be used
    // if you want to put them in a different namespace
    funcName = funcName || "docReady";
    baseObj = baseObj || window;
    var readyList = [];
    var readyFired = false;
    var readyEventHandlersInstalled = false;

    // call this when the document is ready
    // this function protects itself against being called more than once
    function ready() {
        if (!readyFired) {
            // this must be set to true before we start calling callbacks
            readyFired = true;
            for (var i = 0; i < readyList.length; i++) {
                // if a callback here happens to add new ready handlers,
                // the docReady() function will see that it already fired
                // and will schedule the callback to run right after
                // this event loop finishes so all handlers will still execute
                // in order and no new ones will be added to the readyList
                // while we are processing the list
                readyList[i].fn.call(window, readyList[i].ctx);
            }
            // allow any closures held by these functions to free
            readyList = [];
        }
    }

    function readyStateChange() {
        if ( document.readyState === "complete" ) {
            ready();
        }
    }

    // This is the one public interface
    // docReady(fn, context);
    // the context argument is optional - if present, it will be passed
    // as an argument to the callback
    baseObj[funcName] = function(callback, context) {
        if (typeof callback !== "function") {
            throw new TypeError("callback for docReady(fn) must be a function");
        }
        // if ready has already fired, then just schedule the callback
        // to fire asynchronously, but right away
        if (readyFired) {
            setTimeout(function() {callback(context);}, 1);
            return;
        } else {
            // add the function and context to the list
            readyList.push({fn: callback, ctx: context});
        }
        // if document already ready to go, schedule the ready function to run
        if (document.readyState === "complete") {
            setTimeout(ready, 1);
        } else if (!readyEventHandlersInstalled) {
            // otherwise if we don't have event handlers installed, install them
            if (document.addEventListener) {
                // first choice is DOMContentLoaded event
                document.addEventListener("DOMContentLoaded", ready, false);
                // backup is window load event
                window.addEventListener("load", ready, false);
            } else {
                // must be IE
                document.attachEvent("onreadystatechange", readyStateChange);
                window.attachEvent("onload", ready);
            }
            readyEventHandlersInstalled = true;
        }
    }
})("docReady", window);

Najnowsza wersja kodu jest udostępniana publicznie na Githubie pod adresem https://github.com/jfriend00/docReady

Użycie:

// pass a function reference
docReady(fn);

// use an anonymous function
docReady(function() {
    // code here
});

// pass a function reference and a context
// the context will be passed to the function as the first argument
docReady(fn, context);

// use an anonymous function with a context
docReady(function(context) {
    // code here that can use the context argument that was passed to docReady
}, ctx);

To zostało przetestowane w:

IE6 and up
Firefox 3.6 and up
Chrome 14 and up
Safari 5.1 and up
Opera 11.6 and up
Multiple iOS devices
Multiple Android devices

Wdrożenie robocze i stanowisko testowe: http://jsfiddle.net/jfriend00/YfD3C/


Oto podsumowanie jak to działa:

  1. Create an IIFE (natychmiast wywołane wyrażenie funkcji), dzięki czemu możemy mieć Niepubliczne zmienne stanu.
  2. Declare a public function docReady(fn, context)
  3. po wywołaniu docReady(fn, context) sprawdź, czy program obsługi ready już uruchomił. Jeśli tak, po prostu zaplanuj nowo dodane callback do uruchomienia zaraz po tym, jak ten wątek JS zakończy się setTimeout(fn, 1).
  4. jeśli ready handler nie został jeszcze uruchomiony, dodaj to nowe wywołanie zwrotne do listy wywołań zwrotnych, które zostaną wywołane później.
  5. sprawdź, czy dokument jest już gotowy. Jeśli tak, wykonaj wszystkie gotowi.
  6. jeśli nie zainstalowaliśmy jeszcze detektorów zdarzeń, aby wiedzieć, kiedy dokument będzie gotowy, zainstaluj je teraz.
  7. jeśli istnieje document.addEventListener, zainstaluj procedury obsługi zdarzeń za pomocą .addEventListener() zarówno dla zdarzeń "DOMContentLoaded", jak i "load". "Load" to zdarzenie zapasowe dla bezpieczeństwa i nie powinno być potrzebne.
  8. jeśli document.addEventListener nie istnieje, zainstaluj procedury obsługi zdarzeń za pomocą .attachEvent() dla zdarzeń "onreadystatechange" i "onload".
  9. w zdarzeniu onreadystatechange sprawdź, czy document.readyState === "complete", a jeśli tak, wywołaj funkcja odpalania wszystkich gotowych uchwytów.
  10. we wszystkich innych programach obsługi zdarzeń, wywołaj funkcję, która odpali wszystkie gotowe programy obsługi.
  11. w funkcji do wywołania wszystkich gotowych programów obsługi, sprawdź zmienną stanu, aby sprawdzić, czy już uruchomiliśmy. Jeśli tak, to nic nie rób. Jeśli nie zostaliśmy jeszcze wywołani, to wykonujemy pętlę przez tablicę gotowych funkcji i wywołujemy każdą z nich w kolejności, w jakiej zostały dodane. Ustaw flagę, aby wskazać, że wszystkie zostały wywołane, aby nigdy nie były wykonywane więcej niż raz.
  12. Wyczyść tablicę funkcji, aby wszelkie zamknięcia, których mogą używać, mogły zostać uwolnione.

Handlerzy zarejestrowani w {[28] } są zwolnieni w kolejności, w jakiej zostali zarejestrowani.

Jeśli wywołasz docReady(fn) Po tym, jak dokument jest już gotowy, wywołanie zwrotne zostanie zaplanowane do wykonania, gdy tylko bieżący wątek wykonania zakończy się za pomocą setTimeout(fn, 1). Dzięki temu kod wywołujący może zawsze zakładać, że są to wywołania asynchroniczne, które zostaną wywołane później, nawet jeśli później jest tak szybko, jak zakończy się bieżący wątek JS i zachowa kolejność wywołania.

 2175
Author: jfriend00,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-11 21:24:27

Jeśli robisz VANILLA plain JavaScript bez jQuery, musisz użyć (Internet Explorer 9 lub nowszy):

document.addEventListener("DOMContentLoaded", function(event) {
    // Your code to run since DOM is loaded and ready
});

Powyżej jest odpowiednikiem jQuery .ready:

$(document).ready(function() {
    console.log("Ready!");
});

Które również można zapisać w ten sposób, który jQuery uruchomi się po wystąpieniu gotowego parzystości .

$(function() {
    console.log("ready!");
});

Nie należy mylić z poniższym (który nie ma być gotowy do DOM):

Nie używaj IFE W ten sposób, który jest sobą wykonanie:

 Example:

(function() {
   // Your page initialization code here  - WRONG
   // The DOM will be available here   - WRONG
})();
To życie nie będzie czekać, aż twój DOM się załaduje. (Mówię nawet o najnowszej wersji przeglądarki Chrome!)
 190
Author: Tom Stickel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-08 18:31:20

Chciałbym wymienić niektóre z możliwych sposobów tutaj wraz z czysty trick javascript, który działa we wszystkich przeglądarkach :

// with jQuery 
$(document).ready(function(){ /* ... */ });

// shorter jQuery version 
$(function(){ /* ... */ });

// without jQuery (doesn't work in older IEs)
document.addEventListener('DOMContentLoaded', function(){ 
    // your code goes here
}, false);

// and here's the trick (works everywhere)
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}
// use like
r(function(){
    alert('DOM Ready!');
});

Sztuczka tutaj, jak wyjaśniono przez oryginalnego autora , polega na tym, że sprawdzamy dokument.właściwość readyState. Jeśli zawiera łańcuch in (Jak w uninitialized i loading, dwa pierwsze DOM ready Stany z 5) ustawiamy timeout i sprawdzamy ponownie. W przeciwnym razie wykonujemy przekazaną funkcję.

Oraz oto jsFiddle do sztuczki, która działa we wszystkich przeglądarkach.

Podziękowania dla } Tutorialzine za włączenie tego do swojej książki.

 176
Author: Ram Patra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-04 05:18:30

Testowane w IE9, najnowsze Firefox i Chrome, a także obsługiwane w IE8.

document.onreadystatechange = function () {
  var state = document.readyState;
  if (state == 'interactive') {
      init();
  } else if (state == 'complete') {
      initOnCompleteLoad();
  }
}​;

Przykład: http://jsfiddle.net/electricvisions/Jacck/

Aktualizacja-Wersja wielokrotnego użytku

Właśnie opracowałem następujące. Jest to dość uproszczony odpowiednik jQuery lub Dom ready bez wstecznej kompatybilności. Prawdopodobnie wymaga dalszego udoskonalenia. Testowany w najnowszych wersjach Chrome, Firefox i IE (10/11) i powinien działać w starszych przeglądarkach zgodnie z komentarzem. Zaktualizuję, jeśli znajdę jakieś problemy.

window.readyHandlers = [];
window.ready = function ready(handler) {
  window.readyHandlers.push(handler);
  handleState();
};

window.handleState = function handleState () {
  if (['interactive', 'complete'].indexOf(document.readyState) > -1) {
    while(window.readyHandlers.length > 0) {
      (window.readyHandlers.shift())();
    }
  }
};

document.onreadystatechange = window.handleState;

Użycie:

ready(function () {
  // your code here
});

Jest napisany do obsługi asynchronicznego ładowania JS, ale możesz najpierw zsynchronizować załaduj ten skrypt, chyba że minifikujesz. Uważam, że jest to przydatne w rozwoju.

Nowoczesne przeglądarki obsługują również asynchroniczne Ładowanie skryptów, co dodatkowo poprawia wrażenia. Obsługa asynchronizacji oznacza, że wiele skryptów można pobrać jednocześnie, cały czas renderując stronę. Tylko uważaj, gdy zależy od innych skryptów ładowane asynchronicznie lub użyj minifier lub czegoś takiego jak browserify do obsługi zależności.

 80
Author: PhilT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-03 07:46:51

Dobrzy ludzie w HubSpot mają zasób, w którym można znaleźć czyste metody Javascript do osiągnięcia wielu dobroci jQuery-w tym ready

Http://youmightnotneedjquery.com/#ready

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

Przykładowe użycie inline:

ready(function() { alert('hello'); });
 24
Author: Lorcan O'Neill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-28 17:39:15

Nie jestem do końca pewien o co prosisz, ale może to pomoże:

window.onload = function(){
    // Code. . .

}

Lub:

window.onload = main;

function main(){
    // Code. . .

}
 11
Author: Zak The Hat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-13 14:01:36

Twoja metoda (umieszczanie skryptu przed zamykającym znacznikiem body)

<script>
   myFunction()
</script>
</body>
</html>

To niezawodny sposób obsługi starych i nowych przeglądarek.

 8
Author: Kernel James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-28 16:38:38

Gotowe

function ready(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();}

Użyj jak

ready(function(){
    //some code
});

Do samodzielnego wywołania kodu

(function(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();})(function(){

    //Some Code here
    //DOM is avaliable
    //var h1s = document.querySelector("h1");

});

Wsparcie: IE9 +

 6
Author: Vitim.us,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-24 05:15:53

Oto wyczyszczona, nie-evalowa wersja Ram-swaroop ' S "działa we wszystkich przeglądarkach"--działa we wszystkich przeglądarkach!

function onReady(yourMethod) {
  var readyStateCheckInterval = setInterval(function() {
    if (document && document.readyState === 'complete') { // Or 'interactive'
      clearInterval(readyStateCheckInterval);
      yourMethod();
    }
  }, 10);
}
// use like
onReady(function() { alert('hello'); } );

To jednak czeka na dodatkowe 10 ms do uruchomienia, więc oto bardziej skomplikowany sposób, który nie powinien:

function onReady(yourMethod) {
  if (document.readyState === 'complete') { // Or also compare to 'interactive'
    setTimeout(yourMethod, 1); // Schedule to run immediately
  }
  else {
    readyStateCheckInterval = setInterval(function() {
      if (document.readyState === 'complete') { // Or also compare to 'interactive'
        clearInterval(readyStateCheckInterval);
        yourMethod();
      }
    }, 10);
  }
}

// Use like
onReady(function() { alert('hello'); } );

// Or
onReady(functionName);

Zobacz Jak sprawdzić, czy DOM jest gotowy bez frameworka?.

 4
Author: rogerdpack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-13 16:00:19

document.ondomcontentready=function(){} powinno wystarczyć, ale nie ma pełnej kompatybilności przeglądarki.

Wydaje się, że powinieneś używać jQuery min

 3
Author: maxhud,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-16 22:47:57