jQuery preventDefault() not triggered
Asked Answered
C

6

33

I have the following code:

$(document).ready(function(){

    $("div.subtab_left li.notebook a").click(function(event) {
    event.preventDefault();
    return false;   
    });

});

but when I click the element .. it doesn't prevent the default action .. Why?

and when modifying the code to:

$(document).ready(function(){

    $("div.subtab_left li.notebook a").click(function() {
    e.preventDefault();
    alert("asdasdad");
    return false;   
    });

});

it stops the default action but does not alert .. I couldn't find any answer on jQuery docs.

The full code goes like this:

$(document).ready(function(){

$('#tabs div.tab').hide();
$('#tabs div.tab:first').show();
$('#tabs ul li:first').addClass('active');

$('#tabs ul li a').click(function(){
$('#tabs ul li').removeClass('active');
$(this).parent().addClass('active');
var currentTab = $(this).attr('href');
$('#tabs div.tab').hide();
$(currentTab).show();
return false;
});

    $("div.subtab_left li.notebook a").click(function(e) {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();

    alert("asdasdad");
    return false;

    });

});

and the HTML structure is:

<div id="tabs">
<ul id="nav">
<li><a id="tab1" href="#tab-1"></a></li>
<li><a id="tab2" href="#tab-2"></a></li>
<li><a id="tab3" href="#tab-3"></a></li>
<li><a id="tab4" href="#tab-4"></a></li>
</ul>

<div class="tab" id="tab-1">
        <script type="text/javascript">$(document).ready(function(){$("ul.produse li").hover(function () {
        $("ul.produse li").removeClass('active');$(this).addClass('active');}, function () {$(this).removeClass('active');});});
    </script>

    <div class="subtab_left"> 
        <ul>
            <li class="notebook"><a href="#">1</a></li>
            <li class="netbook"><a href="#">2</a></li>      
            <li class="allinone"><a href="#">2</a></li> 
            <li class="desktop"><a href="#">2</a></li> 
            <li class="procesoare"><a href="#">2</a></li> 
            <li class="placi_video"><a href="#">2</a></li>    
            <li class="hdd_desktop"><a href="#">2</a></li>
            <li class="tv_plasma"><a href="#">2</a></li>
            <li class="tv_lcd"><a href="#">2</a></li>
            <li class="telefoane_mobile last_item"><a href="#">2</a></li>
        </ul>
    </div>
Cancan answered 10/4, 2011 at 19:21 Comment(1)
Nope. No error .. the 1st code does alert() but won't prevent default action .. the 2nd code doesn't alert() but prevent default action .. :(Cancan
Z
55

Update

And there's your problem - you do have to click event handlers for some a elements. In this case, the order in which you attach the handlers matters since they'll be fired in that order.

Here's a working fiddle that shows the behaviour you want.

This should be your code:

$(document).ready(function(){


    $('#tabs div.tab').hide();
    $('#tabs div.tab:first').show();
    $('#tabs ul li:first').addClass('active');

    $("div.subtab_left li.notebook a").click(function(e) {
        e.stopImmediatePropagation();
        alert("asdasdad");
        return false;
    });

    $('#tabs ul li a').click(function(){
        alert("Handling link click");
        $('#tabs ul li').removeClass('active');
        $(this).parent().addClass('active');
        var currentTab = $(this).attr('href');
        $('#tabs div.tab').hide();
        $(currentTab).show();
        return false;
    });

});

Note that the order of attaching the handlers has been exchanged and e.stopImmediatePropagation() is used to stop the other click handler from firing while return false is used to stop the default behaviour of following the link (as well as stopping the bubbling of the event. You may find that you need to use only e.stopPropagation).

Play around with this, if you remove the e.stopImmediatePropagation() you'll find that the second click handler's alert will fire after the first alert. Removing the return false will have no effect on this behaviour but will cause links to be followed by the browser.

Note

A better fix might be to ensure that the selectors return completely different sets of elements so there is no overlap but this might not always be possible in which case the solution described above might be one way to consider.


  1. I don't see why your first code snippet would not work. What's the default action that you're seeing that you want to stop?

    If you've attached other event handlers to the link, you should look into event.stopPropagation() and event.stopImmediatePropagation() instead. Note that return false is equivalent to calling both event.preventDefault and event.stopPropagation()ref

  2. In your second code snippet, e is not defined. So an error would thrown at e.preventDefault() and the next lines never execute. In other words

    $("div.subtab_left li.notebook a").click(function() {
        e.preventDefault();
        alert("asdasdad");
        return false;   
    });
    

    should be

    //note the e declared in the function parameters now
    $("div.subtab_left li.notebook a").click(function(e) {
        e.preventDefault();
        alert("asdasdad");
        return false;   
    });
    

Here's a working example showing that this code indeed does work and that return false is not really required if you only want to stop the following of a link.

Zootoxin answered 10/4, 2011 at 19:27 Comment(7)
the only thing that work is e.stopPropagation() + e.stopImmediatePropagation() using both ... why ?Cancan
Those methods stop the bubbling of the event - you must have some other handlers for this click event that also get fired and do something you're not expecting. You current JavaScript looks fine in isolation. Can you post other relevant parts of your code? Or even better, make a fiddle which demonstrates the code not working.Zootoxin
I have some jQuery tabs ... and within the tabs i have some ul li a to trigger another event .. i will post the code .. i assume you're right because that could be the only thing that goes wrong - I also have hover property in css for that <a> elementCancan
Yes you were right all along .. i have $('#tabs ul li a').click(function(){ which also apply on my other <a> ..so i've modified it like this $('#tabs ul#nav li a').click(function(){ and now it's working fine ... it was the ul#nav missing :)Cancan
Great, you've found a better fix than I just suggested in my update - by using a more specific selector you completely avoid the problem!Zootoxin
e.stopImmediatePropagation(); + return false; for the win!Schleswigholstein
On the other hand, my problem just now, was that I was stupid and typo'd the line immediately preceding the preventDefault in a way that caused a runtime error. Turns out if your click handler hits a runtime error, your javascript might stop running, but that does not stop the form from being submitted! So check that, too!Mozzetta
H
7

Try this one:

   $("div.subtab_left li.notebook a").click(function(e) {
    e.preventDefault();
    return false;   
    });
Horse answered 10/4, 2011 at 19:28 Comment(1)
From a jQuery event handler, returning false has exactly the same effect as calling both "preventDefault()" and "stopPropagation()" on the event object. Thus, if a handler returns false, there's no need to call "preventDefault()".Zouave
S
4

If e.preventDefault(); is not working you must use e.stopImmediatePropagation(); instead.

For further informations take a look at : What's the difference between event.stopPropagation and event.preventDefault?

$("div.subtab_left li.notebook a").click(function(e) {
    e.stopImmediatePropagation();
    return false;
});
Synonymize answered 25/10, 2016 at 7:31 Comment(1)
developer.mozilla.org/en-US/docs/Web/API/Event/…Keishakeisling
E
2

Try this:

$("div.subtab_left li.notebook a").click(function(e) {
    e.preventDefault();
});
Ebullience answered 10/4, 2011 at 19:25 Comment(2)
@Cancan well, the thing is, it does work. What that means is that there must be something else wrong on your page or with your JavaScript. If you post more of it, perhaps somebody can figure out the issue.Zouave
Yes , thanks a lot .. it was something wrong with the code .. at the line $('#tabs ul li a').click(function(){ all was needed to modify was ul#nav that ul was applying to multiple <li><a> in my code .. Thanks .. thumb's up !Cancan
C
1

If you already test with a submit action, you have noticed that not works too.

The reason is the form is alread posted in a $(document).read(...

So, all you need to do is change that to $(document).load(...

Now, in the moment of you browaser load the page, he will execute.

And will work ;D

Casket answered 7/6, 2013 at 20:55 Comment(0)
K
1

i just had the same problems - have been testing a lot of different stuff. but it just wouldn't work. then i checked the tutorial examples on jQuery.com again and found out:

your jQuery script needs to be after the elements you are referring to !

so your script needs to be after the html-code you want to access!

seems like jQuery can't access it otherwise.

Krys answered 19/12, 2013 at 23:12 Comment(1)
It does not need to come after the elements you are referring to, it only needs to run after they are added to the DOM. He is doing that by using $(document).ready();.Doublereed

© 2022 - 2024 — McMap. All rights reserved.