5

I'm playing with stopPropagation, adapting code from an MDC doc.

Here's the question: Everything works fine if I do what they did and use element.addEVentListener("click", fname).
But, when I try to attach the function with the element's onclick attribute ( <div onclick="fname();"> ), propagation does not stop.
And if I use <div onclick="function(ev) {fname();}">, fname() isn't called at all (I also tried passing fname(ev) with the same results).

Ideas anyone? Let me know if you need to see the code.

animuson
  • 53,861
  • 28
  • 137
  • 147
Nathan
  • 6,772
  • 11
  • 38
  • 55

2 Answers2

9

Actually, your event acts in the following ways:

Event Fires, Capturing Phase, Bubbling phase, Event has Default Action applied.

Thus, in order to stop propagation you can do the following:

element1.addEventListener('click',fname,true)  // Capturing phase
element1.addEventListener('click',fname,false) // Bubbling phase

fname(event){
  event.stopPropagation();
//event.preventDefault(); is also available here (in both phases I believe)
}

Please note that propagation can only be stopped during the bubbling phase, and only using event handlers in this way allows you to interrupt an event.

As far as I know the tradidtional method of

<div onclick="return fname();">

does not allow this functionality.

gradbot
  • 13,732
  • 5
  • 36
  • 69
GAgnew
  • 3,847
  • 3
  • 26
  • 28
8

When you do this:

<div onclick="fname();">

You're not assigning fname as the event handler, you're calling fname from within your event handler (which is an anonymous function created for you). So your first parameter is whatever you pass into fname, and in your quoted code, you're not passing anything into it.

You'd want:

<div onclick="fname(event);">

But even that won't be reliable, because it assumes that either the auto-generated anonymous function accepts the event parameter using the name event or that you're using IE or a browser that does IE-like things and you're looking at IE's global window.event property.

The more reliable thing to do is this:

<div onclick="return fname();">

...and have fname return false if it wants to both stop propagation and prevent the browser's default action.

All of this why I strongly advocate always using DOM2 methods (addEventListener, which is attachEvent — with slightly different arguments — on IE prior to IE9) to hook up handlers if you want to do anything interesting in the event (or, 9 times out of 10, even if you don't).


Off-topic: And this whole area is one of the reasons I recommend using a library like jQuery, Prototype, YUI, Closure, or any of several others to smooth over browser differences for you so you can concentrate on your own work.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    I'd actually refute that and recommend against using a common framework. Although they have their advantages, a cross-browser framework implementation can be created rather easily. I'd recommend at least writing your own custom framework first such that you can fully understand all the things going on under the hood. This helps you not run into problems like this one in the future! Putting things out of mind, out of site, (and in a framework) is bad practice! Easier does not mean faster, or better! – GAgnew Apr 18 '11 at 15:01
  • J. Good to know, thanks! I'll stick to addEventListener for now. Otherwise, I do use jQuery for this sort of thing. This was just a quick test page, so I hadn't linked to jQ yet. – Nathan Apr 18 '11 at 15:16
  • 1
    @Greg: *"...a cross-browser framework implementation can be created rather easily..."* Oh, so many people have thought that over the years. :-) Just take a look through the source code of any major library, and if you're anything like me, you'll appreciate the ability to leverage all of that debugging other people have done. Like dealing with the fact that Safari will mis-report the selected item in a `select` box in certain situations, or how you have to be careful where you insert `script` elements on IE6 to avoid running into a weird `base` element error. Etc. *(cont'd)* – T.J. Crowder Apr 18 '11 at 15:31
  • @Greg: *(continuing)* Completely agreed you must know what's going on under the hood, but I still wouldn't fly alone on this one, and I'm *famous* amongst my collegues for my tendency to say "Oh, it can't be that complicated, let's just do our own..." ;-) – T.J. Crowder Apr 18 '11 at 15:32