1

I understand event bubbling and how it traverses up the dom from the inner-most element. I am curious as to why this is the default behaviour?

<div>1
    <div>2
        <div>3
            <div>4
                <div>5</div>
            </div>
        </div>
    </div>
</div>

If I have an event listener on each part but click the <div>5</div> why does the event bubble up to div4, div3, div2(etc)'s event listeners?

EDIT: I don't see this as a duplicate of "what is event bubbling" because this is asking why not what

irl_irl
  • 3,785
  • 9
  • 49
  • 60
  • 1
    If you have an event listener on the `
    5
    ` only, you don't experience any bubbling.
    – Bergi Oct 05 '16 at 19:38
  • Well, imagine you that the second `div` represents a button and the inner ones are just elements inside (holding an icon, some text, perhaps). When a user clicks anywhere inside there, you'd want to treat the button as clicked, correct? So you could just attack a click handler on there, instead of _every single element_ under it. – VLAZ Oct 05 '16 at 19:39
  • 1
    http://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing#answer-4616720 – adeneo Oct 05 '16 at 19:40
  • 1
    It does so because the specification says thats what it's supposed to do. It also makes it a lot easier to handle clicks on an element, when that click can also propogate from it's childnodes, and makes event delegation possible, – adeneo Oct 05 '16 at 19:41
  • @Bergi You're right, changed the question slightly. If there were event listeners on each of the divs – irl_irl Oct 05 '16 at 19:42
  • @adeneo yeah it's in the spec, but why is it designed like that? Why not just handle the event in the div that is clicked and then not bubble to other event handlers – irl_irl Oct 05 '16 at 19:43
  • 1
    The whole point of bubbling is that you only need one event listener on the outermost element, which will fire regardless where inside the element the event is triggered. – Bergi Oct 05 '16 at 19:44
  • 9
    If you've been to Geneva, you've been to Switzerland as well. If you've clicked on div5, you've clicked on div4 as well. – Siguza Oct 05 '16 at 19:44
  • 1
    The truth is that we can probably only speculate why it was designed like that (since none of us actually worked on the spec I believe). But yeah, conceptually what @Siguza said makes sense. – Felix Kling Oct 05 '16 at 19:46
  • 2
    Think about it, if any nested element you clicked didn't fire the parents event handler, and the target **had** to be the same element that the handler was attached to, you'd have ten times the work when just creating a simple webpage. – adeneo Oct 05 '16 at 19:47
  • It doesn't just bubble. There is a capturing phase too where the event travels down the DOM tree http://www.quirksmode.org/js/events_order.html – Timmy O'Mahony Oct 05 '16 at 19:49
  • Those are two different models, if you want to use capturing instead, all modern browsers support it by passing in `true` as the third argument in `addEventListener` etc. but the default is bubbling – adeneo Oct 05 '16 at 19:51
  • What you are asking is unclear: Are you wanting to know why the event handlers on all ancestor elements are called *at all*? Are you wanting to know why they are called in children first order for the Bubbling phase? Or why the order is capture phase (ancestors first)➞target phase➞Bubbling phase (children first)? – Makyen Oct 05 '16 at 20:10
  • 1
    very good question. I see no reason why people vote this down. He is asking for a reason and not for an answer like "because the spec says so". In programming you should know why you are doing something. – Ini Aug 21 '18 at 22:30

2 Answers2

2

If you're asking why this is the default behaviour, then the answer is because the language specification says so (emphasis mine):

An event listener consists of these fields:

  • [...]
  • capture (a boolean, initially false)
  • [...]

When an event is dispatched to an object that participates in a tree (e.g. an element), it can reach event listeners on that object’s ancestors too. First all object’s ancestor event listeners whose capture variable is set to true are invoked, in tree order. Second, object’s own event listeners are invoked. And finally, and only if event’s bubbles attribute value is true, object’s ancestor event listeners are invoked again, but now in reverse tree order.

If you're asking why the specification was defined this way, you can ask yourself:
If you've clicked on div5, have you also clicked on div4 or not?
That is ultimately a matter of opinion, but for me the answer is yes, as per my initial comment:

If you've been to Geneva, you've been to Switzerland as well.

Community
  • 1
  • 1
Siguza
  • 21,155
  • 6
  • 52
  • 89
1

Your statement is wrong. The default for simple events is not to bubble:

Firing a simple event named e means that a trusted event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the Event interface, must be created and dispatched at the given target.

So the HTML related events which bubble it's because the spec explicitly says so, presumably because it makes more sense this way.

Some events which bubble:

Some events which do not bubble:

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • Where would you ever want something to bubble up the DOM? An option to stop bubbling and capturing entirely would mean less code and would be less error-prone. "Because the language spec says so" does IMO not answer his question. I guess he is asking about the reason why the spec defines it like this, because to me it seems to be pretty useless as a default mode and does only introduce friction... – Ini Aug 22 '18 at 00:10