Pytanie jQuery.ready () odpowiednik detektor zdarzeń na elementach?


Używam biblioteki JavaScript jQuery. Lubię słuchacza wydarzeń gotowy na $(document) który uruchamia się po skonfigurowaniu DOM.

(Bardzo podobne do .onload, ale bez zewnętrznych źródeł)

Byłbym bardzo przydatny, gdyby był słuchacz wydarzeń, który ma bardzo podobne zachowanie do tego, ale strzela, gdy element jest w pełni załadowany. (f.e .: Picture, Div z wyjątkowo długą zawartością tekstu, np.)

Byłbym wdzięczny zarówno za metody jQuery, jak i JavaScript.


18
2017-10-14 08:01


pochodzenie




Odpowiedzi:


Nie ma zdarzenia uruchamianego, gdy arbitralny element DOM, taki jak <div> staje się gotowy. Obrazy mają swoje load Zdarzenie informujące o tym, kiedy dane obrazu zostały załadowane i wyrenderowane, a kilka innych specjalnych typów elementów ma zdarzenie. Ale zwykłe elementy DOM nie mają takiego zdarzenia.

Jeśli chcesz, aby kod javascript był uruchamiany, gdy tylko dowolny element DOM jest gotowy, jedynym sposobem na to jest wywołanie funkcji w skrypcie wbudowanym zaraz po tym elemencie DOM. W tym momencie element DOM będzie gotowy, ale reszta DOM może nie być jeszcze gotowa. W przeciwnym razie skrypt może zostać umieszczony na końcu dokumentu lub skrypt może zostać uruchomiony, gdy cały dokument jest gotowy.

Oto istniejące zdarzenia ładowania wyrażone w formularzu jQuery (można to zrobić w zwykłym JS):

// when a particular image has finished loading the image data
$("#myImage").load(fn);

// when all elements in the document are loaded and ready for manipulation
$(document).ready(fn);

// when the DOM and all dynamically loaded resources such as images are ready
$(window).load(fn);

W jQuery można również dynamicznie ładować zawartość i otrzymywać powiadomienia, gdy ta zawartość została załadowana za pomocą .load() metoda taka jak ta:

$( "#result" ).load( "ajax/test.html", function() {
  alert( "Load was performed." );
});

Wewnętrznie, to po prostu wykonuje wywołanie ajax, aby pobrać dane, a następnie wywołuje wywołanie zwrotne po tym, jak dane zostały pobrane przez ajax, a następnie wstawione do dokumentu. To nie jest wydarzenie rodzime.


Jeśli masz jakiś kod, który dynamicznie ładuje elementy do DOM i chcesz wiedzieć, kiedy te elementy DOM są obecne, to najlepszym sposobem, aby wiedzieć, kiedy są gotowe, jest posiadanie kodu, który dodaje je do DOM. zdarzenia, aby powiedzieć, kiedy jest gotowe. Zapobiega to marnowaniu baterii na próby pollingu, próbując ustalić, czy element znajduje się teraz w DOM.

Możliwe jest również użycie DOM MutationObserver aby zobaczyć, kiedy określone typy zmian zostały wprowadzone do DOM.


18
2017-10-14 08:10



+1 dla wymagających wyjaśnień - Steven Palinkas
Dodaj informacje o DOM MutationObservers, aby zobaczyć zmiany w DOM. - jfriend00


Wszystkie elementy (w tym div i img) są gotowe, gdy tylko DOMReady wystrzeli - oznacza to.

Możesz jednak użyć load() zdarzenie, aby uruchomić jakiś kod, gdy img znacznik w pełni wczytał obraz do swojej src atrybut:

$('img').load(function() {
   console.log('image loaded');
});

4
2017-10-14 08:08





jQuery go nie ma, ale możemy stworzyć własne narzędzie onDomElementIsReady, Narzędzia: jQuery, ES6, Promise i Interval (Jestem leniwy, ale możesz wpaść na pomysł)

Poczekamy, aż element będzie istnieć w DOM i jak tylko będzie dostępny, rozwiążemy ten problem promise wynik.

  const onDomElementIsReady = (elementToWatch)=> {
    //create promise
    return new Promise((res, rej)=> {
      let idInterval = setInterval(()=> {
        //keep waiting until the element exist
        if($(elementToWatch).length > 0) {
          clearInterval(idInterval); //remove the interval
          res($(elementToWatch)); //resolve the promise             
        }
      },100);
    });
  };


//how to use it?
onDomElementIsReady(".myElement").then(element => { 
                          //use jQuery element
                   });

UWAGA: Aby to poprawić, powinniśmy dodać zegar, który reject obietnica, jeśli element DOM nigdy nie istnieje.


2
2017-08-26 07:20



Bardziej kreatywny niż elegancki. :) Naprawdę doceniam podejście ES6. - Steven Palinkas
@StevenPalinkas - Poważnie, myślisz, że podejście, które przeszukuje DOM co 100ms na zawsze, dopóki nie znajdzie danego elementu DOM jest najlepszym rozwiązaniem? Odpytywanie jest NIGDY najlepszym rozwiązaniem każdego problemu. Jest nieefektywny dla procesora, marnuje baterię na urządzenia mobilne i nie jest bezpośrednio związany z rzeczywistą zmianą. Zamiast tego powinieneś używać powiadomień o zdarzeniach, które są związane z tym, co powoduje zmianę w DOM-ie (coś, co w swoim pytaniu nie zawiera żadnych informacji w twoim pytaniu). - jfriend00
@StevenPalinkas - Plus, twoje pytanie, aby wiedzieć, kiedy obraz jest w pełni załadowany. Nie robi to w żaden sposób. Może powiedzieć, kiedy tag obrazu istnieje w DOM, ale nie wtedy, gdy jest załadowany. - jfriend00
Sądzę, że masz rację, to właśnie zamierzałem zaznaczyć, że nie jest elegancka. Zastanowię się nad znakiem akceptacji. - Steven Palinkas