222

While using PhoneGap, it has some default JavaScript code that uses document.addEventListener, but I have my own code which uses window.addEventListener:

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

What is the difference and which is better to use?

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Charlie
  • 11,380
  • 19
  • 83
  • 138
  • Related [What is the difference between window, screen, and document in JavaScript?](https://stackoverflow.com/questions/9895202/what-is-the-difference-between-window-screen-and-document-in-javascript) – Liam Feb 18 '23 at 13:48

4 Answers4

270

The document and window are different objects and they have some different events. Using addEventListener() on them listens to events destined for a different object. You should use the one that actually has the event you are interested in.

For example, there is a "resize" event on the window object that is not on the document object.

For example, the "readystatechange" event is only on the document object.

So basically, you need to know which object receives the event you are interested in and use .addEventListener() on that particular object.

Here's an interesting chart that shows which types of objects create which types of events: https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference


If you are listening to a propagated event (such as the click event), then you can listen for that event on either the document object or the window object. The only main difference for propagated events is in timing. The event will hit the document object before the window object since it occurs first in the hierarchy, but that difference is usually immaterial so you can pick either. I find it generally better to pick the closest object to the source of the event that meets your needs when handling propagated events. That would suggest that you pick document over window when either will work. But, I'd often move even closer to the source and use document.body or even some closer common parent in the document (if possible).

jdkramhoft
  • 278
  • 1
  • 7
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 2
    I was curious about the "bubbling up to the document but not the window" thing. So I tested it here -> http://jsfiddle.net/k3qv9/1/ Am I missing something or does the bubbling actually occur? – João Paulo Macedo Aug 20 '12 at 21:43
  • 1
    @JOPLOmacedo - before your comment, I removed the part about bubbling as I because unsure which events bubble to the window and which do not. The protocol I've always seen is to intercept document wide bubbling events at the `document.body` object or the `document` object so there is no reason to use `window` for bubbled events. In any case the point of my answer is that some events are only on `window` and some events are only on `document` and some are on both so the OP should pick the object that corresponds to the event they want to handle. – jfriend00 Aug 20 '12 at 21:47
  • Okey dokey. That's what I usually do too - exactly why I decided to test it. Thanks for the answer! – João Paulo Macedo Aug 20 '12 at 21:52
  • 1
    Since 'click' event is available in both document and window and if we register event on both document and window then the click handler of document fire first then window. so for this point of view choice of document is better. http://www.jsfiddle.net/3LcVw/ – coder Aug 02 '14 at 19:47
  • @MohammadSaeedKhan - For events that bubble up to `document` and `window` (like `click`), it makes no difference which one you put them on. Whether your event handler gets the click some fraction of a ms sooner on one versus the other won't make any difference. From a code cleanliness point of view, it seems more logical to me that event handlers attached to the `window` should be events that happen to the window itself (like resize). And then it seems more logical to me that event handlers on the `document` are things that actually happen to the document (like `click` or `keyup`). – jfriend00 Aug 02 '14 at 20:51
  • @jfriend00 since document is property (and object) of the global window object i think that the first sentence might be misleading (assuming 2 completely different objects) ? – Vitaliy Terziev Nov 28 '15 at 09:17
  • @vtz - They are two completely different objects. It does not matter if one happens to have a reference to the other stored in a property. They are two completely different objects and listening to events on one object does not listen to the events that only occur on the other object. – jfriend00 Nov 28 '15 at 16:17
  • what about document.body and document for adding listeners – SuperUberDuper Apr 18 '16 at 10:52
  • @SuperUberDuper - `document` and `document.body` are different DOM elements and thus have different events. You should use the DOM element that has the event you want. For events that bubble, you could probably use either since anything that bubbles to `document.body` will also bubble to `document`. I tend to pick the closest element I can to the source for bubbling events which would mean I'd pick `document.body` over `document`. – jfriend00 Apr 18 '16 at 16:33
  • 1
    Another example: If you will add `addEventListener("keydown", event)` via `window` for Samsung TV, than it won't work. But you will do the same thing with `document`, then it will. Depends also on specific device how it calls bubbled events. – Jakub Kubista Jan 20 '20 at 11:17
  • in capturing phase which one is first, window or document – Muhammad Umer Dec 25 '21 at 21:11
  • is there something above window – Muhammad Umer Dec 25 '21 at 21:11
  • @MuhammadUmer - `document` is before `window`. I'm not aware of anything past `window`. – jfriend00 Dec 26 '21 at 08:08
  • Depending on what you actually want, there are differences between putting `click` on `document` vs `window`. It is possible via CSS to make document cover less than entire visible area, and clicks in the "background" area will reach only `window`, but not `document`. On the other hand, in some browsers `click` event fires on scrollbars and reaches `window`, but not `document`, so to avoid breaking something you may need to add some checking (e.g. access to some event properties from on-page JS is denied on the window scrollbar). – f2d Mar 01 '22 at 17:44
6

The window binding refers to a built-in object provided by the browser. It represents the browser window that contains the document. Calling its addEventListener method registers the second argument (callback function) to be called whenever the event described by its first argument occurs.

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

Following points should be noted before select window or document to addEventListners

  1. Most of the events are same for window or document but some events like resize, and other events related to loading, unloading, and opening/closing should all be set on the window.
  2. Since window has the document it is good practice to use document to handle (if it can handle) since event will hit document first.
  3. Internet Explorer doesn't respond to many events registered on the window,so you will need to use document for registering event.
AConsumer
  • 2,461
  • 2
  • 25
  • 33
4

You'll find that in javascript, there are usually many different ways to do the same thing or find the same information. In your example, you are looking for some element that is guaranteed to always exist. window and document both fit the bill (with just a few differences).

From mozilla dev network:

addEventListener() registers a single event listener on a single target. The event target may be a single element in a document, the document itself, a window, or an XMLHttpRequest.

So as long as you can count on your "target" always being there, the only difference is what events you're listening for, so just use your favorite.

Bryan Wolfford
  • 2,102
  • 3
  • 20
  • 26
  • 9
    This is not generically true. Different events occur on different objects. `document` and `window` do not receive the same events. You must choose the object that gets the event you are interested in. Some events may go to both `document` and `window`, but not all. – jfriend00 Aug 20 '12 at 21:38
0

In my opinion, it is generally better to pick the closest object to the source of the event that meets your needs when handling propagated events.

So, if you want the event to happen to the element, it's better to use window.addEventListener() (assume the window variable is an element) because the most important thing here when listening to an event is that the code and event execution work faster: the only thing that matters in this case.

godot
  • 1,550
  • 16
  • 33