Różnica między document.addEventListener i window.addEventListener?

135

Podczas korzystania z PhoneGap ma domyślny kod JavaScript, który używa document.addEventListener, ale mam własny kod, który używa window.addEventListener:

function onBodyLoad(){
    document.addEventListener("deviceready", onDeviceReady, false);
    document.addEventListener("touchmove", preventBehavior, false);
    window.addEventListener('shake', shakeEventDidOccur, false);
}

Jaka jest różnica i która jest lepsza w użyciu?

Charlie
źródło

Odpowiedzi:

160

Te documenti windowsą różnymi obiektami i mają różne zdarzenia. Za pomocąaddEventListener() na nich nasłuchuje zdarzeń przeznaczonych dla innego obiektu. Powinieneś użyć tego, który faktycznie ma wydarzenie, które Cię interesuje.

Na przykład "resize"w windowobiekcie istnieje zdarzenie, którego nie ma w documentobiekcie.

Na przykład "DOMContentLoaded"zdarzenie dotyczy tylko documentobiektu.

Zasadniczo musisz wiedzieć, który obiekt odbiera interesujące Cię zdarzenie i którego używasz .addEventListener()na tym konkretnym obiekcie.

Oto interesujący wykres, który pokazuje, jakie typy obiektów tworzą poszczególne typy zdarzeń: https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference


Jeśli nasłuchujesz propagowanego zdarzenia (takiego jak zdarzenie kliknięcia), możesz nasłuchiwać tego zdarzenia na obiekcie dokumentu lub obiekcie okna. Jedyną główną różnicą w przypadku propagowanych wydarzeń jest czas. Zdarzenie uderzy w documentobiekt przed windowobiektem, ponieważ występuje jako pierwsze w hierarchii, ale ta różnica jest zwykle nieistotna, więc możesz wybrać jedną z nich. Uważam, że generalnie lepiej jest wybrać obiekt najbliżej źródła zdarzenia, który spełnia Twoje potrzeby podczas obsługi propagowanych zdarzeń. Które sugerowałyby, że wybierzesz documentsię window, gdy albo będzie działać. Ale często zbliżałem się jeszcze bardziej do źródła i używam document.bodylub nawet bliżej wspólnego rodzica w dokumencie (jeśli to możliwe).

jfriend00
źródło
Zaciekawiło mnie to „bulgotanie do dokumentu, ale nie do okna”. Przetestowałem to tutaj -> jsfiddle.net/k3qv9/1 Czy coś mi brakuje, czy faktycznie występuje bulgotanie?
banzomaikaka
1
@JOPLOmacedo - przed twoim komentarzem usunąłem część o bulgotaniu jak ja, ponieważ nie jestem pewien, które zdarzenia bąbelkują do okna, a które nie. Protokół, który zawsze widziałem, polega na przechwytywaniu zdarzeń propagacji w całym dokumencie w document.bodyobiekcie lub documentobiekcie, więc nie ma powodu, aby używać go w windowprzypadku zdarzeń propagacji . W każdym razie celem mojej odpowiedzi jest to, że niektóre zdarzenia są tylko włączone, windowa niektóre tylko, documenta niektóre są na obu, więc OP powinien wybrać obiekt, który odpowiada zdarzeniu, które chce obsłużyć.
jfriend00
OK, OK. To też zwykle robię - właśnie dlatego zdecydowałem się to przetestować. Dziękuję za odpowiedź!
banzomaikaka
Ponieważ zdarzenie „click” jest dostępne zarówno w dokumencie, jak i oknie, a jeśli zarejestrujemy zdarzenie zarówno w dokumencie, jak i oknie, najpierw zostanie uruchomiony moduł obsługi kliknięcia dokumentu, a następnie okno. więc z tego punktu widzenia wybór dokumentu jest lepszy. jsfiddle.net/3LcVw
koder
1
Inny przykład: jeśli dodasz addEventListener("keydown", event)przez windowdla telewizora Samsung, to nie zadziała. Ale zrobisz to samo z document, a potem tak się stanie. Zależy również od konkretnego urządzenia, w jaki sposób wywołuje zdarzenia propagowane.
Jakub Kubista
4

Przekonasz się, że w javascript jest zwykle wiele różnych sposobów zrobienia tego samego lub znalezienia tych samych informacji. W swoim przykładzie szukasz elementu, który z pewnością będzie istniał zawsze. windowidocument oba pasują do rachunku (z kilkoma różnicami).

Z sieci deweloperów Mozilli :

addEventListener () rejestruje pojedynczy detektor zdarzeń w jednym miejscu docelowym. Celem zdarzenia może być pojedynczy element w dokumencie, sam dokument, okno lub XMLHttpRequest.

Tak długo, jak możesz liczyć na to, że Twój „cel” zawsze tam jest, jedyną różnicą jest to, jakich wydarzeń słuchasz, więc po prostu użyj swojego ulubionego.

Bryan Wolfford
źródło
5
Nie jest to generalnie prawdą. Na różnych obiektach zachodzą różne zdarzenia. documenti windownie otrzymuj tych samych wydarzeń. Musisz wybrać obiekt, który odbierze interesujące Cię zdarzenie. Niektóre zdarzenia mogą dotyczyć obu documenti window, ale nie wszystkich.
jfriend00
1

windowWiązania odnosi się do wbudowanego obiektu przewidziane przez przeglądarkę. Reprezentuje okno przeglądarki zawierające rozszerzenie document. Wywołanie jej addEventListenermetody rejestruje drugi argument (funkcję zwrotną), który ma zostać wywołany, gdy wystąpi zdarzenie opisane przez pierwszy argument.

<p>Some paragraph.</p>
<script>
  window.addEventListener("click", () => {
    console.log("Test");
  });
</script>

Poniższe punkty należy zanotować przed wybraniem okna lub dokumentu do dodaniaEventListners

  1. Większość zdarzeń są takie same dla windowalbo documentale niektóre zdarzenia jak resizei inne wydarzenia związane loading, unloadingorazopening/closing powinny być ustawione w oknie.
  2. Ponieważ okno ma dokument, dobrą praktyką jest używanie dokumentu do obsługi (jeśli potrafi obsłużyć), ponieważ zdarzenie uderzy najpierw w dokument.
  3. Internet Explorer nie reaguje na wiele zdarzeń zarejestrowanych w oknie, więc będziesz musiał użyć dokumentu do rejestracji zdarzenia.
AConsumer
źródło