Cameron
Cameron

Reputation: 4201

Jquery multiple events when only one wanted

With the following html and jQuery, if I click the first anchor multiple times and then click the list anchor I get the alert message show up by the number of times I clicked the first anchor. Why is this? How do I stop it happening?

<div>
    <a href="#">click me</a>
    <ul style="display:none">
        <li><a href='#'>now click me</a></li>
    </ul>
</div>


$('div > a').click(function(e) {
    e.preventDefault();

    $(this).next().show().find('a').click(function() {
        alert("alert from inner click");
        return false;
    });
});

Upvotes: 0

Views: 249

Answers (5)

Michael Sagalovich
Michael Sagalovich

Reputation: 2549

if you really want to bind the second click handler inside the first one, you can wrap the second handler into a function and first try to unbind this function:

$(this).next().show().find('a')
    .unbind("click", someFunction)
    .click(someFunction);

you can also set some flag to true inside second handler to check whether it was called before.

But as far as I see the main question here is why return false does not stop event propagating, right? This needs some further research, as I expected it to work.

Upvotes: 0

Coin_op
Coin_op

Reputation: 10718

Basically when you click the first link you attach a new click event to the nested link. There are two solutions to this.

Firstly you can unbind the second click event before you set it again:

$('div > a').click(function(e) {
    e.preventDefault();

    $(this).next().show().find('a')
        .unbind('click')
        .click(function() {
            alert("alert from inner click");
            return false;
        });
});

The other and better solution is to attach the other click outside the first click event.

Upvotes: 0

Fred Bergman
Fred Bergman

Reputation: 2020

This is happening because you are binding a click event on the anchor inside the list everytime you click the first link.

What do you want to achieve?

Upvotes: 0

Reto Aebersold
Reto Aebersold

Reputation: 16624

Maybe you can use event.stopPropagation()

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074305

Because every time your click handler for the anchor is called, you're hooking up another instance of an event handler for the other anchor. Presumably you only want to hook it up once, but without knowing more about what you're trying to actually do...

If you're trying to change what happens on the second anchor when you click the first, you can unbind all click handlers from the anchor first, like this:

$('div > a').click(function(e) {
    e.preventDefault();

    $(this).next().show().find('a').unbind('click').click(function() {
        // New bit is here.........^^^^^^^^^^^^^^^^
        alert("alert from inner click");
        return false;
    });
});

...but I suspect with a better idea of the overall goal, there would be a better solution. (One problem of the above is that it removes all click handlers from the anchor, whether hooked up by that code or something else, which isn't playing nicely with others.)

Upvotes: 3

Related Questions