Menu Search
Jump to the content X X
Smashing Conf Barcelona

You know, we use ad-blockers as well. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. our upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

An Introduction To DOM Events

Click, touch, load, drag, change, input, error, resize — the list of possible DOM events is lengthy. Events can be triggered on any part of a document, whether by a user’s interaction or by the browser. They don’t just start and end in one place; they flow through the document, on a life cycle of their own. This life cycle is what makes DOM events so extensible and useful. As a developer, you should understand how DOM events work, so that you can harness their potential and build engaging experiences.

Throughout my time as a front-end developer, I felt that I was never given a straight explanation of how DOM events work. My aim here is to give you a clear overview of the subject, to get you up to speed more quickly than I did.

Further Reading on SmashingMag: Link

I will introduce the basics of working with DOM events, then delve into their inner workings, explaining how we can make use of them to solve common problems.

Listening For DOM Events Link

In the past, browsers have had major inconsistencies in the way they attach event listeners to DOM nodes. Libraries such as jQuery5 have been invaluable in abstracting away these oddities.

As we move ever closer to standardized browser environments, we can more safely use the APIs from the official specification. To keep it simple, I will describe how to manage events for the modern Web. If you are writing JavaScript for Internet Explorer (IE) 8 or below, I would advise using a polyfill6 or framework (such as jQuery7) to manage event listeners.

In JavaScript, we can listen to events using this:

element.addEventListener(<event-name>, <callback>, <use-capture>);
  • event-name (string)
    This is the name or type of event that you would like to listen to. It could be any of the standard DOM events (click, mousedown, touchstart, transitionEnd, etc.) or even your own custom event name (we’ll touch on custom events later).
  • callback (function)
    This function gets called when the event happens. The event object, containing data about the event, is passed as the first argument.
  • use-capture (boolean)
    This declares whether the callback should be fired in the “capture” phase. (Don’t worry: We’ll explain what that means a little later.)
var element = document.getElementById('element');

function callback() {

// Add listener
element.addEventListener('click', callback);

Demo: addEventListener8

Removing Listeners Link

Removing event listeners once they are no longer needed is a best practice (especially in long-running Web applications). To do this, use the element.removeEventListener() method:

element.removeEventListener(<event-name>, <callback>, <use-capture>);

But removeEventListener has one catch: You must have a reference to the callback function that was originally bound. Simply calling element.removeEventListener('click'); will not work.

Essentially, if we have any interest in removing event listeners (which we should in “long-lived” applications), then we need to keep a handle on our callbacks. This means we cannot use anonymous functions.

var element = document.getElementById('element');

function callback() {
  alert('Hello once');
  element.removeEventListener('click', callback);

// Add listener
element.addEventListener('click', callback);

Demo: removeEventListener9

Maintaining Callback Context Link

An easy gotcha is callbacks being called with the incorrect context. Let’s explain with an example.

var element = document.getElementById('element');

var user = {
 firstname: 'Wilson',
 greeting: function(){
   alert('My name is ' + this.firstname);

// Attach user.greeting as a callback
element.addEventListener('click', user.greeting);

// alert => 'My name is undefined'

Demo: Incorrect callback context10

Using Anonymous Functions Link

We expected the callback to correctly alert us with My name is Wilson. In fact, it alerts us with My name is undefined. In order for this.firstName to return Wilson, user.greeting must be called within the context (i.e. whatever is left of the dot when called) of user.

When we pass the greeting function to the addEventListener method, we are only passing a reference to the function; the context of user is not passed with it. Internally, the callback is called in the context of element, which means that this refers to element, not to user. Therefore, this.firstname is undefined.

There are two ways to prevent this context mismatch. First, we can call user.greeting() with the correct context inside an anonymous function.

element.addEventListener('click', function() {
  // alert => 'My name is Wilson'

Demo: Anonymous functions11

Function.prototype.bind Link

The last method isn’t so good because now we don’t have a handle on the function when we want to remove it with .removeEventListener(). Plus, it’s pretty ugly. I prefer to use the .bind()12 method (built into all functions, as of ECMAScript 5) to generate a new function (bound) that will always run in the given context. We then pass that function as the callback to .addEventListener().

// Overwrite the original function with
// one bound to the context of 'user'
user.greeting = user.greeting.bind(user);

// Attach the bound user.greeting as a callback
button.addEventListener('click', user.greeting);

We also have a reference to the callback at hand, which we can use to unbind the listener if need be.

button.removeEventListener('click', user.greeting);

Demo: Function.prototype.bind13


The Event Object Link

The event object is created when the event first happens; it travels with the event on its journey through the DOM. The function that we assign as a callback to an event listener is passed the event object as its first argument. We can use this object to access a wealth of information about the event that has occurred:

  • type (string)
    This is the name of the event.
  • target (node)
    This is the DOM node where the event originated.
  • currentTarget (node)
    This is the DOM node that the event callback is currently firing on.
  • bubbles (boolean)
    This indicates whether this is a “bubbling” event (which we’ll explain later16).
  • preventDefault (function)
    This prevents any default behaviour from occurring that the user agent (i.e. browser) might carry out in relation to the event (for example, preventing a click event on an <a> element from loading a new page).
  • stopPropagation (function)
    This prevents any callbacks from being fired on any nodes further along the event chain, but it does not prevent any additional callbacks of the same event name from being fired on the current node. (We’ll talk about that later17.)
  • stopImmediatePropagation (function)
    This prevents any callbacks from being fired on any nodes further along the event chain, including any additional callbacks of the same event name on the current node.
  • cancelable (boolean)
    This indicates whether the default behaviour of this event can be prevented by calling the event.preventDefault18 method.
  • defaultPrevented (boolean)
    This states whether the preventDefault method has been called on the event object.
  • isTrusted (boolean)
    An event is said to be “trusted” when it originates from the device itself, not synthesized from within JavaScript.
  • eventPhase (number)
    This number represents the phase that the event is currently in: none (0), capture (1), target (2) or bubbling (3). We’ll go over event phases next19.
  • timestamp (number)
    This is the date on which the event occurred.

Many other properties can be found on the event object, but they are specific to the type of event in question. For example, mouse events will include clientX and clientY properties on the event object to indicate the location of the pointer in the viewport.

It’s best to use your favorite browser’s debugger or a console.log to look more closely at the event object and its properties.

Event Phases

When a DOM event fires in your app, it doesn’t just fire once where the event originated; it embarks on a journey of three phases. In short, the event flows from the document’s root to the target (i.e. capture phase), then fires on the event target (target phase), then flows back to the document’s root (bubbling phase).

dom events20
(Image source: W3C21)

Demo: Slow motion event path22

Capture Phase Link

The first phase is the capture phase. The event starts its journey at the root of the document, working its way down through each layer of the DOM, firing on each node until it reaches the event target. The job of the capture phase is to build the propagation path, which the event will travel back through in the bubbling phase.

As mentioned, you can listen to events in the capture phase by setting the third argument of addEventListener to true. I have not found many use cases for capture phase listeners, but you could potentially prevent any clicks from firing in a certain element if the event is handled in the capture phase.

var form = document.querySelector('form');

form.addEventListener('click', function(event) {
}, true); // Note: 'true'

If you’re unsure, listen for events in the bubbling phase by setting the useCapture flag to false or undefined.

Target Phase Link

An event reaching the target is known as the target phase. The event fires on the target node, before reversing and retracing its steps, propagating back to the outermost document level.

In the case of nested elements, mouse and pointer events are always targeted at the most deeply nested element. If you have listened for a click event on a <div> element, and the user actually clicks on a <p> element in the div, then the <p> element will become the event target. The fact that events “bubble” means that you are able to listen for clicks on the <div> (or any other ancestor node) and still receive a callback once the event passes through.

Bubbling Phase

After an event has fired on the target, it doesn’t stop there. It bubbles up (or propagates) through the DOM until it reaches the document’s root. This means that the same event is fired on the target’s parent node, followed by the parent’s parent, continuing until there is no parent to pass the event onto.

Think of the DOM as an onion and the event target as the core of the onion. In the capture phase, the event drills into the onion through each layer. When the event reaches the core, it fires (the target phase), and then reverses, working its way back up through each layer (the propagation phase). Once the event has returned to the surface, its journey is over.

Bubbling is useful. It frees us from listening for an event on the exact element it came from; instead, we listen on an element further up the DOM tree, waiting for the event to reach us. If events didn’t bubble, we would have to, in some cases, listen for an event on many different elements to ensure that it is caught.

Demo: Identifying event phases23

The majority of, but not all, events bubble. When events do not bubble, it is usually for a good reason. If in doubt, check the specification24.

Stopping Propagation

Interrupting the path of the event at any point on its journey (i.e. in the capture or bubbling phase) is possible simply by calling the stopPropagation method on the event object. Then, the event will no longer call any listeners on nodes that it travels through on its way to the target and back to the document.

child.addEventListener('click', function(event) {

parent.addEventListener('click', function(event) {
 // If the child element is clicked
 // this callback will not fire

Calling event.stopPropagation() will not prevent any additional event listeners from being called on the current target if multiple listeners for the same event exist. If you wish to prevent any additional listeners from being called on the current node, you can use the more aggressive event.stopImmediatePropagation() method.

child.addEventListener('click', function(event) {

child.addEventListener('click', function(event) {
 // If the child element is clicked
 // this callback will not fire

Demo: Stopping propagation25

Prevent The Browser’s Default Behavior

The browser has default behaviors that will respond when certain events occur in the document. The most common event is a link being clicked. When a click event occurs on an <a> element, it will bubble up to the document level of the DOM, and the browser will interpret the href attribute and reload the window at the new address.

In Web applications, developers usually want to manage the navigation themselves, without causing the page to refresh. To do this, we need to prevent the browser’s default response to clicks and instead do our own thing. To do this, we call event.preventDefault().

anchor.addEventListener('click', function(event) {
  // Do our own thing

We can prevent many other default behaviors in the browser. For example, we could prevent presses of the space bar from scrolling the page in an HTML5 game, or we could prevent clicks from selecting text.

Calling event.stopPropagation() here will only prevent callbacks that are attached further down the propagation chain from being fired. It will not prevent the browser from doing its thing.

Demo: Preventing default behavior26

Custom DOM Events Link

The browser is not the only thing that is able to trigger DOM events. We can create our own custom events and dispatch them on any element in the document. This type of event would behave just the same as a regular DOM event.

var myEvent = new CustomEvent("myevent", {
  detail: {
    name: "Wilson"
  bubbles: true,
  cancelable: false

// Listen for 'myevent' on an element
myElement.addEventListener('myevent', function(event) {
  alert('Hello ' +;

// Trigger the 'myevent'

Synthesizing “untrusted” DOM events on elements (for example, click) to simulate user interaction is also possible. This can be useful when testing DOM-related libraries. If you’re interested, the Mozilla Developer Network has a write-up on it27.

Note the following:

  • The CustomEvent API is not available in IE 8 and below.
  • The Flight28 framework from Twitter makes use of custom events to communicate between modules. This enforces a highly decoupled, modular architecture.

Demo: Custom events29

Delegate Event Listeners Link

Delegate event listeners are a more convenient and performant way to listen for events on a large number of DOM nodes using a single event listener. For example, if a list contains 100 items that all need to respond to a click event in a similar way, then we could query the DOM for all of the list items and attach an event listener to each one. This would result in 100 separate event listeners. Whenever a new item is added to the list, the click event listener would have to be added to it. Not only does this risk getting expensive, but it is tricky to maintain.

Delegate event listeners can make our lives a lot easier. Instead of listening for the click event on each element, we listen for it on the parent <ul> element. When an <li> is clicked, then the event bubbles up to the <ul>, triggering the callback. We can identify which <li> element has been clicked by inspecting the Below is a crude example to illustrate:

var list = document.querySelector('ul');

list.addEventListener('click', function(event) {
  var target =;

  while (target.tagName !== 'LI') {
    target = target.parentNode;
    if (target === list) return;

  // Do stuff here

This is better because we have only the overhead of a single event listener, and we no longer have to worry about attaching a new event listener when an item is added to the list. The concept is pretty simple but super-useful.

I wouldn’t recommend using such a crude implementation in your app. Instead, use an event delegate JavaScript library, such as FT Lab’s ftdomdelegate30. If you’re using jQuery, you can seamlessly use event delegation by passing a selector as the second parameter to the .on() method.

// Not using event delegation
$('li').on('click', function(){});

// Using event delegation
$('ul').on('click', 'li', function(){});

Demo: Delegate event listeners31

Useful Events Link

load Link

The load event fires on any resource that has finished loading (including any dependent resources). This could be an image, style sheet, script, video, audio file, document or window.

image.addEventListener('load', function(event) {

Demo: Image load event32

onbeforeunload Link

window.onbeforeunload enables developers to ask the user to confirm that they want to leave the page. This can be useful in applications that require the user to save changes that would get lost if the browser’s tab were to be accidentally closed.

window.onbeforeunload = function() {
  if (textarea.value != textarea.defaultValue) {
    return 'Do you want to leave the page and discard changes?';

Note that assigning an onbeforeunload handler prevents the browser from caching the page33, thus making return visits a lot slower. Also, onbeforeunload handlers must be synchronous.

Demo: onbeforeunload34

Stopping Window bounce in Mobile Safari Link

At the Financial Times, we use a simple event.preventDefault technique to prevent mobile Safari from bouncing the window when it is scrolled.

document.body.addEventListener('touchmove', function(event) {

Be warned that this will also prevent any native scrolling from working ( such as overflow: scroll). To allow native scrolling on a subset of elements that need it, we listen for the same event on the scrollable element and set a flag on the event object. In the callback at the document level, we decide whether to prevent the default behavior of the touch event based on the existence of the isScrollable flag.

// Lower down in the DOM we set a flag
scrollableElement.addEventListener('touchmove', function(event) {
 event.isScrollable = true;

// Higher up the DOM we check for this flag to decide
// whether to let the browser handle the scroll
document.addEventListener('touchmove', function(event) {
 if (!event.isScrollable) event.preventDefault();

Manipulating the event object is not possible in IE 8 and below. As a workaround, you can set properties on the node.

resize Link

Listening to the resize event on the window object is super-useful for complex responsive layouts. Achieving a layout with CSS alone is not always possible. Sometimes JavaScript has to help us calculate and set the size of elements. When the window is resized or the device’s orientation changes, then we would likely need to readjust these sizes.

window.addEventListener('resize', function() {
  // update the layout

I recommended using a debounced35 callback to normalize the callback rate and prevent extreme thrashing in the layout.

Demo: Window resizing36

transitionEnd Link

Today we use CSS to power the majority of transitions and animations in our applications. Sometimes, though, we still need to know when a particular animation has finished.

el.addEventListener('transitionEnd', function() {
 // Do stuff

Note the following:

  • If you’re using @keyframe animations, use the animationEnd event name, instead of transitionEnd.
  • Like a lot of events, transitionEnd bubbles. Remember either to call event.stopPropagation() on any descendant transition events or to check the to prevent callback logic from running when it’s not supposed to.
  • Event names are still widely vendor-prefixed (for example, webkitTransitionEnd, msTransitionEnd, etc). Use a library such as Modernizr37 to get the event name’s correct prefix.

Demo: Transition end38

animationiteration Link

The animationiteration event will fire every time a currently animating element completes an iteration. This is useful if we want to stop an animation but not midway through.

function start() {

function stop() {
  div.addEventListener('animationiteration', callback);

  function callback() {
    div.removeEventListener('animationiteration', callback);

If you’re interested, I’ve written about the animationiteration event39 in a little more detail on my blog.

Demo: Animation iteration40

error Link

If an error occurs when a resource loads, we might want to do something about it, especially if our users are on a flaky connection. The Financial Times uses this event to detect any images that might have failed to load in an article and instantly hide them. Because the “DOM Level 3 Events41” specification has redefined the error event to “not bubble,” we can handle the event in one of two ways.

imageNode.addEventListener('error', function(event) { = 'none';

Unfortunately, addEventListener does not address all use cases. My colleague Kornel5042 has kindly pointed me to an example that demonstrates43 that the only way, sadly, to guarantee the execution of image error event callbacks is to use (the often frowned upon) inline event handlers.

<img src="" onerror="'none';" />

The reason for this is that you cannot be sure that the code that binds the error event handler will be executed before the error event actually happens. Using inline handlers means that when the markup is parsed and the image is requested, our error listeners will be attached.

Demo: Image error44

Lessons From The Event Model Link

A lot can be learned from the success of the DOM events model. We can employ similar decoupled concepts in our own projects. Modules in an application can be as complex as they need to be, so long as that complexity is sealed away behind a simple interface. Many front-end frameworks (such as Backbone.js) are heavily event-based, solving cross-module communication in a publish and subscribe model that is very similar to the DOM.

Event-based architectures are great. They give us a simple common interface in which to write applications that respond to physical interactions across thousands of devices! Via events, devices tell us exactly what has happened and when it occurred, letting us respond however we please. What goes on behind the scenes is not of concern; we get a level of abstraction that frees us to get on with building our awesome app.

Further Reading Link

Special thanks to Kornel5042 for a brilliant technical review.

(al, il)

Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16 #bubble-phase
  17. 17 #stopping-propagation
  18. 18 #preventing-default
  19. 19 #event-phases
  20. 20
  21. 21
  22. 22,js,output
  23. 23
  24. 24
  25. 25,js,output
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50

↑ Back to top Tweet itShare on Facebook

Wilson is a front-end developer at FT Labs in London. He enjoys pushing the limits of responsive design, and dreams in JavaScript. You can follow him on Twitter for frequent front-end goodness.

  1. 1

    Great article, but is there is a situation where you’d use that over something like

    $('element').on('event',function(){ //do something });


    • 2

      Chris Heilmann

      November 12, 2013 4:09 am

      Maybe when you don’t want to use jQuery, for example on a mobile device? Why use a swiss army knife when you need a toothpick?

    • 4

      How about ?

      `var $ = document.querySelector.bind(document);
      Element.prototype.on = Element.prototype.addEventListener;
      $(“somelink”).on(‘touchstart’, handleTouch);`

  2. 5

    Thank you so much for the article. Gonna be a very helpful one.

    By the way, recently I was working on a project where I wanted to hide all the elements when the mouse is idle for a few seconds. I was able to use some simple javascript code and achieve that. But the problem was, when the mouse was kept on top the element that was supposed to hidden, it just flickers once and appears back.
    Any idea how can we overcome that issue and get it work as we intended? Even if I tried other scripts, most of them has this same issue.

  3. 14

    Great article – the demo’s are helpful too!

  4. 15

    Regarding the delegate event thing, I’ve been using an alternative method. Your way:

    var list = document.querySelector('ul');
    list.addEventListener('click', function(event) {
        while (target.tagName !== 'LI') {
            target = target.parentNode;
            if (target === list) return;
        // Do stuff here});

    However I do it like this:

    var list = document.querySelector('ul');
    list.addEventListener('click', function(event) {
        if (target.tagName !== "LI") {
        // Do stuff here

    It’s simpler, but I’m wondering which would be faster – your way is essentially bubbling up the tree manually, whereas I’m simply waiting for the bubble to hit the element I need.

    • 16

      Hi Andy!

      Your method would work for simple markup, but consider if you had other elements inside the <li> such as an <h1>. If the user clicked the <h1> element we would still want want the click handler for the <li> to fire, but the === ‘H1’.

      We therefore have to start at the target and walk up the DOM checking each node in turn until we reach the element which the original event handler was bound.

      Hope this makes sense! I can amend the wording of the article if you have any suggestions :)

      • 17

        if you want only the ‘s handler to fire, and ignore other things, then set “capturing” to true. Otherwise, let the event bubble like Andy suggested. You walking up the DOM yourself has these drawbacks:

        1. It’s not performant — try not to walk the DOM unless you absolutely have to. You have a great tool to use here: bubbling. So use it.
        2. If the was wrapped inside a which is wrapped by your , and the also has a handler on it, and the handler on the needs to run before the handler on the runs, then you manually walking up the DOM from the to run the handler on the would break the intended order of the event handlers.

        Again, just let it bubble and all will be fine.

        • 18

          Gah, don’t know how to use the comment tools here to show markups so the HTML tags don’t show up. Ah well.

    • 19

      Are CSS point-events also capable of mitigating some of this? (I’m asking because I do not entirely know myself)

      • 20

        I guess potentially, but sounds like dangerous territory. I wouldn’t view this as a bug, this is how events in the DOM are designed to work :)

  5. 21

    very cool!

  6. 22

    “In order for to return Wilson, user.greeting must…”

    Shouldn’t be

    “In order for this.firstname to return Wilson, user.greeting must…”


  7. 24

    Nice article, thank you!

    I’m missing DOMContentLoaded in the Useful Events section.
    The first Delegate Event Listeners code example shows target where it should be This section might also use element.matches() for a (much) simpler delegation target identification.

    • 25

      Thanks for the typo I have fixed :)

      1. Regarding DOMContentLoaded, you’re right, we should probably add that to the article at some point.
      2. element.matches() is super useful, I have used it in the past. But in this example I wanted to more demonstrate the the core concept of event delegation in the simplest, most familiar way for beginners. Maybe we should consider updating the example to use more modern APIs though, I’ll give it some thought :)

  8. 26

    Very nice article

  9. 27

    I enjoyed this post, thanks for writing it – like you say it isn’t something that is widely talked about, front end developers just kind of pick it up as they go along.

    I will certainly be pointing people to this article that run into difficulties with DOM events.

  10. 28

    Well, that was a pretty amazing piece of writing. Thanks a lot Wilson.

  11. 29

    Hi! Great article. Thank you.

    One question, how much of this is already standard in the browsers? I programmed DOM when Netscape 4 and IE 5 were the browsers and making every decent web page meant several consults on


    • 30

      You can safely use element.addEventListener in IE9+. If you have to support lesser platforms I would advise using a an abstraction like jQuery.

  12. 31

    Jessica Bracken

    November 12, 2013 10:11 pm

    I like the post, great stuff. Thanks a lot for sharing.

  13. 32

    Hi, thank you for a nice overview of DOM events.

    One more thing worth mentioning might be, that you can also pass an object implementing handleEvent method as the second argument to addEventListener. The potential advantage is, that this in the handleEvent method will automatically refer to the passed object and not the element (which can still be accessed through event.currentTarget).

    var obj = {
        name: 'Joe',
        handleEvent: function(event) {
            console.log('Hi, my name is %s.',;
    element.addEventListener('click', obj, false);
  14. 34

    Great article!
    One little mistake: an Event does not have a name, but is of some (named) type.
    So the description of Event.type and the signatures of addEventListener and removeEventListener should be aligned with the spec, see and e.g.

  15. 35

    Personal authority

    November 13, 2013 5:51 am

    An Introduction To DOM Events article is important for web developer .Thanks for sharing this useful information! Hope that you will continue with the kind of stuff you are doing.

  16. 36

    Wow, this “Introduction” was very instructive.

    Understanding DOM events is a must for web developers so thanks a lot for all these clear and detailed explanations.

    On a side note I love the _.debounce() method. I learned something super important here about the resize event.

    I have bookmarked this article and already recommended it.

    Thanks again :)

  17. 37

    Vladimir Carrer

    November 13, 2013 7:51 am

    Great article!

    Long time ago .. I made this function for Event Delegation
    today I have non idea why or how I wrote this code, but somehow it works :)

  18. 38

    santosh sharma

    November 14, 2013 1:30 am

    This is an AWESOME article… I have never come across such a simple language article which explains about the most complex part (DOM Events) of JavaScript and with simple examples. Thanks a lot again for sharing it… :)

  19. 39

    Hi Wilson,
    Great post!

    Regarding the last point about accurate error reporting on images, Paul Irish/Desandro’s library imagesloaded is tremendously useful, particularly the event ‘fail’, which fires after all images have been loaded and at least one is confirmed broken.

  20. 40

    Share your knowledge! Thanks for so full article.

  21. 41

    This is a good learning format for me. Simple, concise explanations of specific DOM components with examples in JS Bin to play with. On behalf of my grey matter, thank you.

  22. 42

    Maybe you should correct timestamp to timeStamp.

    Great article =)

  23. 43

    Fantastic article. Concise, very clear, and the examples really helped me to understand DOM events.

  24. 44

    Very thorough. I’m impressed!

  25. 45

    Great article, thank you for taking the time to write it.

  26. 46

    Very nice article, but a bit longer than it should be.

  27. 47

    I think the things i’m intested is the e.currentTarget when you bind a event to a element which has child elements while ie didn’t this property.

  28. 48

    Very practical introduction to a complicated subject. Thanks for sharing your knowledge!

  29. 49

    thanks a lot for the informative article :)

  30. 50
  31. 51

    Thanks for details about event delegation.
    One point is still unclear about events concerning parent or children.
    But I would like to know why, when I use “Inspect element”, and “Event listeners” tab in my browser (Chrome v. 39.0.2171.65 m), I see that, even if I attached an event listener to only a parent Div, I see that this event listener is also registered for each child? This happens if I attach listener with usecapture true or false.
    Does this registration on child is the result of delegation? Is it a virtual attachment that doesn’t use as much memory as a real attachment?
    Does this mean that even if we attach a listener to a parent using capture and don’t want event firing on children (not using delegation), the event will still fire on children so we need to add stopPropagation?

  32. 52

    Please someone update article, the author write transtionEnd instead transitionend.


↑ Back to top