4

I have a click listener on a div and inside the div I have a link with a normal -tag but whenever I click on the link the event is also run. How can I prevent the stuff within the click-listener to run if the click on the link inside the div?

HTML:

<div class="container item-container" data="skarp-version-av-os-x-10.8.3-slappt">
        <div class="item">
            <div class="number">
                <p class="number-data">1</p>
            </div>
            <div class="upvotes btn tooltip-points" points="4" id="90" data-toggle="tooltip" title="" data-original-title="Visar poäng satta de senaste 24 h">
                4 poäng
            </div>
            <div class="item-content">
                <a href="http://feeds.idg.se/~r/idg/ETkj/~3/XSuYKgEiumE/skarp-version-av-os-x-1083-slappt" target="_blank" class="item-link fill-div">Skarp version av OS X 10.8.3 släppt</a>
                <span class="item-source">(feeds.idg.se)</span>
                <p class="item-author">Upplagd av Anonym - <em>2013-03-17 21:07:08</em></p>
            </div>
            <div class="comment">
                <i class="icon-comment"></i> <a href="http://www.tldr.nu/item/view/skarp-version-av-os-x-10.8.3-slappt#disqus_thread">0 Comments and 0 Reactions</a>
            </div>
        </div>
    </div>

Javascript:

$('.item-container').click(function(event) {
    var url = $(this).attr('data') ? $(this).attr('data') : '';
    if(url != '')
        window.location = getBaseURL() + 'item/view/' + url;
});
Filburt
  • 17,626
  • 12
  • 64
  • 115
Ms01
  • 4,420
  • 9
  • 48
  • 80

5 Answers5

2

You could either add an event handler on the link that stops the click event from bubbling up to the div, or you could add an if-statement inside the handler for the div so it ignores the click event when the event target is the link. I think the former solution would be the way to go.

This sets an event handler on the link that stops the click event from propagating up to the div:

$('.item-container a').click(function(event) {
   event.stopPropagation();
});

jsfiddle demo

John S
  • 21,212
  • 8
  • 46
  • 56
1

You'll either need to bind a specific prevention method to the inner elements, like this -

$("a").click(function(e){
    e.stopPropagation();
});

or you'll need to sniff for the clicked element's type -

$(".wrap").click(function(e){
    if ($(e.target).hasClass("wrap")){
       alert("click");
    }
});

The second method is usually preferable, since for this question to arise, your inner elements have events of their own that you want to function fairly normally.

However, maybe you want the links to not trigger the parent div effect when they're clicked, in which case the first is better.

Fiddle - http://jsfiddle.net/WXzjP/

iabw
  • 1,108
  • 1
  • 9
  • 24
  • Doesn't a `return false` behave like bith `event.preventDefault()` and `event.stopPropagation()` were called? – rodneyrehm Mar 17 '13 at 22:22
  • Yeah, just lazy writing. Fixed. – iabw Mar 17 '13 at 22:25
  • I'm curious, why do you say Brad's answer is not helpful in this instance? Didn't he just show the second technique you show? – John S Mar 17 '13 at 22:32
  • At first he just showed return false. I'll edit that out too. – iabw Mar 17 '13 at 22:40
  • None of these answers matter anyway, as people should be getting a real understanding of event bubbling - http://stackoverflow.com/questions/1357118/event-preventdefault-vs-return-false/1357151#1357151 – iabw Mar 17 '13 at 22:43
0
$('.item-container').click(function(event) {
    if(!$(event.target).is('a')) {
        var url = $(this).attr('data') ? $(this).attr('data') : '';
        if(url != '')
            window.location = getBaseURL() + 'item/view/' + url;
    }
});

Check if the event target that initiated the event is an anchor element, and if it isn't, execute your function.

Brad M
  • 7,857
  • 1
  • 23
  • 40
0

Familiarize yourself with Event Bubbling - you'll need to understand the basics to eventually understand Event Delegation.

You can solve your problem in one of two ways. Either bind a click event to the <a> within your <div> and call event.stopPropagation();, or have the <div>'s event handler check the event.target for being an <a> element:

if (event.target.nodeName.toLowerCase() === 'a') {
  // <a> was clicked
}
rodneyrehm
  • 13,442
  • 1
  • 40
  • 56
0

Because it "bubbles up". Think of it like this;

When you click on your link, it has an action to do as you specify: navigate to a url.. Next, it "bubbles-up" the tree and you also have a click handler for the div, so it tries to run that too.

If you also had a click handler for your $('body') that would also be called.

You have to stop bubbling with event.stopPropagation();

e.g.

$('#your-anchor-tag').click(function(e) {
 e.stopPropagation();
}

That way, you will stop the bubbling up process..

Subliminal Hash
  • 13,614
  • 20
  • 73
  • 104