de-vraag
  • Pytania
  • Tagi
  • Użytkownicy
Powiadomienia
Nagrody
Rejestracja
Po zarejestrowaniu się, będziesz otrzymywać powiadomienia o odpowiedziach i komentarzach do swoich pytań.
Zaloguj się
Brak tłumaczeń pasujących do Twojego wyszukiwania Jeśli masz już konto, zaloguj się, aby sprawdzić nowe powiadomienia.
Za dodane pytania, odpowiedzi i komentarze przewidziane są nagrody.
Więcej
Źródło
Edytuj
 chris
chris
Question

Czysty JavaScriptowy odpowiednik jQuery's $.ready() - jak wywołać funkcję, gdy strona/DOM jest na to gotowa

Ok, to może być tylko głupie pytanie, choć jestem pewien, że jest mnóstwo innych ludzi, którzy zadają to samo pytanie od czasu do czasu. Ja, po prostu chcę się upewnić w 100%, że tak czy inaczej jest to możliwe. Z jQuery wszyscy znamy wspaniałą

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

Jednak powiedzmy, że chcę uruchomić funkcję, która jest napisana w standardowym JavaScripcie bez żadnej biblioteki wspierającej ją, i że chcę uruchomić funkcję, gdy tylko strona jest gotowa do jej obsługi. Jaki jest właściwy sposób podejścia do tego?

Wiem, że mogę zrobić:

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>

Jaka jest zgodna z przeglądarkami (stara/nowa) metoda wydawania jednej lub więcej funkcji w sposób podobny do jQuery's $.ready()?

1231 2012-03-27T23:57:21+00:00 3
Peter Mortensen
Peter Mortensen
Edytowane pytanie 13. października 2017 в 2:06
Programowanie
javascript
html
jquery
Popular videos
What is $document ready function in jquery
What is $document ready function in jquery
7 lat temu
🔥 window.onload VS document.ready 🔥 The Difference
🔥 window.onload VS document.ready 🔥 The Difference
3 lata temu
JavaScript Document object model (DOM) за час. Изменение HTML CSS. Атрибуты и свойства. Окружение.
JavaScript Document object model (DOM) за час. Изменение HTML CSS. Атрибуты и свойства. Окружение.
1 rok temu
Funkcje - Programowanie w JavaScript #13
Funkcje - Programowanie w JavaScript #13
4 lata temu
Zostań Programistą JavaScript #4 - Funkcje - Kurs Javascript
Zostań Programistą JavaScript #4 - Funkcje - Kurs Javascript
1 rok temu
jQuery&#39;s document.ready function in pure vanilla JS
jQuery's document.ready function in pure vanilla JS
2 lata temu
#2 شرح ال JavaScript Dom Document
#2 شرح ال JavaScript Dom Document
4 lata temu
Основы javascript 16 - DOM (объектная модель документа)
Основы javascript 16 - DOM (объектная модель документа)
8 lat temu
JavaScript(JS-Lynda.com)  05 2  Изменение DOM
JavaScript(JS-Lynda.com) 05 2 Изменение DOM
7 lat temu
Jquery: Exercícios diversos de DOM.
Jquery: Exercícios diversos de DOM.
5 lat temu
#5 شرح كيفيه التعامل مع  JavaScript Dom CSS
#5 شرح كيفيه التعامل مع JavaScript Dom CSS
4 lata temu
GeekHub JS 2020 - DOM, jQuery
GeekHub JS 2020 - DOM, jQuery
1 rok temu
Работа с DOM в JS – Урок #14 | Базовый JavaScript
Работа с DOM в JS – Урок #14 | Базовый JavaScript
3 lata temu
JQuery   Manipulation du DOM
JQuery Manipulation du DOM
1 rok temu
JS DOM - Introduction to JS DOM Manipulation | JavaScript Bangla Tutorial
JS DOM - Introduction to JS DOM Manipulation | JavaScript Bangla Tutorial
10 miesięcy temu
« Poprzedni
Następny »
To pytanie ma 1 odpowiedź w języku angielskim, aby je przeczytać zaloguj się na swoje konto.
Solution / Answer
 jfriend00
jfriend00
28. marca 2012 в 12:46
2012-03-28T00:46:22+00:00
Więcej
Źródło
Edytuj
#15791897

Najprostszą rzeczą do zrobienia w przypadku braku frameworka, który robi wszystko dla kompatybilności między przeglądarkami, jest po prostu umieszczenie wywołania do swojego kodu na końcu ciała. Jest to szybsze do wykonania niż obsługa onload, ponieważ czeka tylko na DOM, aby być gotowym, a nie na wszystkie obrazy do załadowania. 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 dowolna wersja Chrome, Firefox lub Safari), jeśli chcesz być w stanie zaimplementować metodę jQuery jak $(document).ready(), którą możesz wywołać z dowolnego miejsca (bez martwienia się o to, gdzie skrypt wywołujący jest umieszczony), możesz po prostu 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 z różnymi przeglądarkami (włączając w to stare wersje IE) i nie chcesz czekać na window.onload, to prawdopodobnie powinieneś przyjrzeć się temu, jak framework taki jak jQuery implementuje swoją metodę $(document).ready(). Jest to dość skomplikowane w zależności od możliwości przeglądarki.

Aby dać ci mały pomysł, co robi jQuery (który będzie działał wszędzie tam, gdzie umieszczony jest znacznik script).

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

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

z opcją awaryjną do:

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

lub dla starszych wersji IE, używa:

document.attachEvent("onreadystatechange", fn);

z opcją awaryjną do:

window.attachEvent("onload", fn);

I, istnieją pewne obejścia w ścieżce kodu IE, które nie'całkiem podążają, ale wygląda na to, że ma to coś wspólnego z ramkami.


Tutaj jest pełny zamiennik dla jQuery's .ready() napisany w zwykłym 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ępniona 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);

Zostało to 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

Robocza implementacja i stanowisko testowe:


Oto podsumowanie tego, jak to działa:

  1. Tworzymy IIFE (natychmiastowo wywoływane wyrażenie funkcyjne), abyśmy mogli mieć niepubliczne zmienne stanu.
  2. Zadeklaruj publiczną funkcję docReady(fn, context).
  3. Kiedy docReady(fn, context) jest wywoływany, sprawdź czy ready handler już wystrzelił. Jeśli tak, po prostu zaplanuj nowo dodany callback tak, aby odpalił się zaraz po tym, jak ten wątek JS zakończy się za pomocą setTimeout(fn, 1).
  4. Jeśli ready handler jeszcze nie wystrzelił, to dodaj ten nowy callback do listy callbacków, które mają być wywołane później.
  5. Sprawdź, czy dokument jest już gotowy. Jeśli tak, to wykonaj wszystkie ready handlery.
  6. Jeśli nie zainstalowaliśmy jeszcze nasłuchu zdarzeń, aby wiedzieć, kiedy dokument będzie gotowy, zainstaluj je teraz.
  7. Jeśli document.addEventListener istnieje, zainstaluj obsługę zdarzeń używając .addEventListener() dla obu zdarzeń "DOMContentLoaded" i "load". Zdarzenie "load" jest zdarzeniem zapasowym dla bezpieczeństwa i nie powinno być potrzebne.
  8. Jeśli document.addEventListener nie istnieje, to zainstaluj obsługę zdarzeń używając .attachEvent() dla zdarzeń "onreadystatechange" i "onload".
  9. W zdarzeniu onreadystatechange sprawdź, czy document.readyState == "complete" i jeśli tak, wywołaj funkcję odpalającą wszystkie ready handlery.
  10. We wszystkich pozostałych event handlerach wywołaj funkcję, aby odpalić wszystkie ready handlery.
  11. W funkcji wywołującej wszystkie ready handlery sprawdź zmienną stanu, czy już się nie odpaliliśmy. Jeśli tak, nie rób nic. Jeśli nie zostaliśmy jeszcze wywołani, to zapętl tablicę gotowych funkcji i wywołaj każdą z nich w kolejności, w jakiej zostały dodane. Ustaw flagę wskazującą, że wszystkie zostały wywołane, aby nigdy nie były wykonywane więcej niż raz.
  12. Wyczyść tablicę funkcji, aby można było uwolnić wszelkie domknięcia, których mogą one używać.

Handlerzy zarejestrowani za pomocą docReady() mają gwarancję, że będą uruchamiane w kolejności w jakiej zostały zarejestrowane.

Jeśli wywołasz docReady(fn) po tym jak dokument jest już gotowy, wywołanie zwrotne zostanie zaplanowane do wykonania jak tylko bieżący wątek wykonania zakończy się używając setTimeout(fn, 1). Pozwala to kodowi wywołującemu 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 tylko zakończy się bieżący wątek JS i zachowuje kolejność wywoływania.

Jan  Kyu Peblik
Jan Kyu Peblik
Edytowana odpowiedź 11. września 2019 в 9:24
1754
0
Kernel James
Kernel James
28. marca 2012 в 12:46
2012-03-28T00:46:12+00:00
Więcej
Źródło
Edytuj
#15791896

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

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

jest niezawodnym sposobem na obsługę starych i nowych przeglądarek.

 rogerdpack
rogerdpack
Edytowana odpowiedź 28. października 2016 в 4:38
7
0
 maxhud
maxhud
28. marca 2012 в 12:04
2012-03-28T00:04:53+00:00
Więcej
Źródło
Edytuj
#15791895

Funkcja document.ondomcontentready=function(){} powinna załatwić sprawę, ale nie ma ona pełnej kompatybilności z przeglądarkami.

Wygląda na to, że powinieneś po prostu użyć jQuery min

 Nakilon
Nakilon
Edytowana odpowiedź 16. maja 2013 в 10:47
1
0
Dodaj pytanie
Kategorie
Wszystkie
Technologia
Kultura / Rekreacja
Życie / Sztuka
Nauka
Profesjonalny
Biznes
Użytkownicy
Wszystkie
Nowy
Popularny
1
365
Zarejestrowany 1 dzień temu
2
True Image
Zarejestrowany 1 dzień temu
3
archana agarwal
Zarejestrowany 3 dni temu
4
Maxim Zhilyaev
Zarejestrowany 6 dni temu
5
adambotsfford adambotsfford
Zarejestrowany 1 tydzień temu
BG
DA
DE
EL
ES
FI
FR
ID
IT
JA
KO
NL
PL
PT
RU
SL
ZH
© de-vraag 2022
Źródło
stackoverflow.com
na podstawie licencji cc by-sa 3.0 z przypisaniem