2

I have several image element that I add during DOM population, I used jQuery "on" to attach click listeners to each image added, in order to prevent propagation of events when an image is clicked I used stopImmediatePropagation, however this doesn't seem to work, image elements already in the page also gets the to acquire the effects. please see my code below:

 html
 <a href="/">Logout<img src=""/></a>
 <div id="1" class="box"><img src=""/></div>
 <div id="2" class="box"><img src=""/></div>
 <div id="3" class="box"><img src=""/></div>

 javascript 
 $(img).on('click', function(e){
    e.stopImmediatePropagation();
    $(this).parent().css({"color":"red"});
    return $(this).parent().attr('id');
 });

when I click the image in the div, the color change propagates to the logout, wherein the color should only affect the div (parent of the img) being clicked.

what could possibly be wrong or the cause?

mirageservo
  • 2,387
  • 4
  • 22
  • 31
  • 1
    Have you tried e.stopPropagation(); ? – Dimag Kharab Jul 02 '15 at 12:23
  • Can you include a live example that shows the problem in action? Such as a JSFiddle – musefan Jul 02 '15 at 12:28
  • 2
    Code works as expected, IMO. "When I click an img tag, set the parent element to have CSS style `color: red`, and return its ID. I think you may be misunderstanding propagation? – Dave Salomon Jul 02 '15 at 12:29
  • you want to set the color red only for clicked `img`s parent `div` ? – dreamweiver Jul 02 '15 at 12:31
  • @DaveSalomon, you are correct, the code works but have you noticed how it affects the Logout which it should not, what I expect is only the parent of the img being clicked should turn red and should not affect the Logout (a href tag) – mirageservo Jul 02 '15 at 12:32
  • What is `img` in your javascript? I wonder if perhaps that isn't what you expect it to be, that might be causing the problem. Certainly what you have posted suggests it works fine – musefan Jul 02 '15 at 12:33
  • You should never need stopPropagation when adding events for images. stopPropagation stops the same event being triggered on parents that match your jquery selector. As images can't be nested (an image can't have a child image), this should never be a problem – James King Jul 02 '15 at 12:58
  • @paul But it _should_ affect the 'Logout' text. The parent element of the first `img` element is the `a` element. It sets the css `color` of the `a` element. What is it you're trying to achieve? http://jsfiddle.net/daveSalomon/69uvsje8/ – Dave Salomon Jul 02 '15 at 12:58
  • Agree with @DaveSalomon, code is working just fine - are you hoping the background colour would change? e.g. http://jsfiddle.net/69uvsje8/3/ – James King Jul 02 '15 at 13:03
  • @DaveSalomon in your example, I can't click the images in the div, (i should) then, try to click it, the Logout turns into red, instead the parent div of the image I've clicked. – mirageservo Jul 02 '15 at 13:03
  • As James King suggested, I suppose I need a good reading about stopPropagation, dreamwiever's answer below is correct (that's what I want to achieve) I just find it unusual, because what I understand that if I click the img, the click event would propagate to all img rather than just the img I've clicked. Am I correct with this assumption? – mirageservo Jul 02 '15 at 13:21
  • No. Propgation is about any other handlers attached to the element being executed, and prevents the event from bubbling up the DOM tree. [This fiddle](http://jsfiddle.net/daveSalomon/4bryngrc/) might make it clearer? :) – Dave Salomon Jul 02 '15 at 13:25
  • @DaveSalomon base on your example, does this mean I have to put the stop propagation to where I want the action propagation not to happen? What would happen if I click that button with stop propagation in it? – mirageservo Jul 02 '15 at 13:38

2 Answers2

0

I Beleive this is what you wanted to achieve,

JS Code:

  $('img').on('click', function(e){
    console.log('click:'+$(this).parent().html());
    $(this).parent().html();
    $(this).parent().css({"background-color":"red"});
    return $(this).parent().attr('id');
  });

Live demo @ JSFiddle:https://jsfiddle.net/dreamweiver/b8wua5xe/3/

Suggestion:try to avoid use of block elements like div inside inline element like a (anchor), also try to keep the dom structure neat & dont clutter multiple elements

dreamweiver
  • 6,002
  • 2
  • 24
  • 39
  • why this code snippet does not need stopImmediatePropagation or the like? – mirageservo Jul 02 '15 at 13:07
  • when `img` is clicked the anchor tag is also triggered,thats why its not preferred to use `div` inside a `anchor` tag. check this http://stackoverflow.com/questions/3092610/div-inside-link-a-href-tag . besides its not good to have block element inside inline element. – dreamweiver Jul 02 '15 at 13:35
0

It sounds like you're wanting to change the background colour, which is the background-color (or just background), not color. Here's a fiddle that does what you're trying to achieve.

I think you're mistaking how jQuery attaches event handlers, and what propagation is all about.

Take this example:

<div>Foo</div>
<div>Bar</div>
<div>Baz</div>

<script>
    $('div').click(function(){
        alert($(this).text());
    });
</script>

What this does is attach a listener to each div. When the div is clicked, it fires the click event, and any listeners attached to that element will fire.

A slightly more complex example:

<div id="divFoo">
    <p id="pFoo">Foo</p>
</div>

<script>
    $('#divFoo').click(function(){
         alert('divFoo');
    });

    $('#pFoo').click(function(){
         alert('pFoo');
    });
</script>

Now divFoo has a click handler, and pFoo has one as well. Note that pFoo's parent (divFoo) has a click handler attached too.

Propogation is to do with the event 'bubbling up' the DOM tree. So, if I click pFoo, the handler will fire. The click event will then 'bubble up' to the parent div, and the divFoo handler will fire. $.stopPropagation prevents this happening.

As an aside, if we have 2 handlers attached to a single element, then $.stopImmediatePropagation will prevent any other handlers firing as well. The order the events fire in is essentially first come first serve, but not quite - there's another Q on Stack about that :).

This fiddle has a more complete example.

Note that the DOM tree is literally, a tree.

-- Root Div    (level 0)  #A
|--- Child P   (level 1)  #B
|--- Child P   (level 1)  #C
|--- Child Div (level 1)  #D
|----- Child P (level 2)  #E
|--- Child P   (level 1)  #F

Let's say I attach a handler to #E. The event will 'bubble' to #D (its parent), and then to #A (its parents parent). It wont touch #B, #C or #F, because they're siblings - not an ancestor.

Dave Salomon
  • 3,287
  • 1
  • 17
  • 29
  • but in my case I have the same element without id's in it, meaning jQuery will recurse to the DOM tree to execute everything it finds with the same element type, in my case the am I correct? – mirageservo Jul 02 '15 at 13:44
  • Nope. I've updated my answer to explain about the DOM tree. The event bubbles up to any ancestors, but wont fire on any siblings. – Dave Salomon Jul 02 '15 at 13:50
  • thank you for holding on for me, great explanation, I appreciate it. because of your explanation, I now have a fair understanding of this topic. – mirageservo Jul 02 '15 at 13:53
  • Happy to help. Good question. :) – Dave Salomon Jul 02 '15 at 13:53