freeMagee
freeMagee

Reputation: 464

jQuery click event triggered multiple times off one click

I am having trouble with multiple clicks being registered in jQuery when only one element has been clicked. I have read some other threads on Stack Overflow to try and work it out but I reckon it is the code I have written. The HTML code is not valid, but that is caused by some HTML 5 and the use of YouTube embed code. Nothing that affects the click.

The jQuery, triggered on document.ready

function setupHorzNav(portalWidth) {
    $('.next, .prev').each(function() {
        $(this).click(function(e) {
            var target = $(this).attr('href');
            initiateScroll(target);
            console.log("click!");
            e.stopPropagation();
            e.preventDefault();
            return false;
        });
    });

    function initiateScroll(target) {
        var position = $(target).offset();
        $('html, body').animate({
            scrollLeft: position.left
        }, 500);
    }
}

Example HTML

<nav class="prev-next">
    <a href="#countdown-wrapper" class="prev">Prev</a>
    <a href="#signup-wrapper" class="next">Next</a>
</nav>

In Firefox one click can log a "Click!" 16 times! Chrome only sees one, but both browsers have shown problems with the above code.

Have I written the code wrongly or is there a bug?

-- Some extra info ------------------------------------------

setupHorzNav is called by another function in my code. I have tested this and have confirmed it is only called once on initial load.

if ( portalWidth >= 1248 ) {
    wrapperWidth = newWidth * 4;
    setupHorzNav(newWidth);
}
else
{
    wrapperWidth = '100%';
}

There are mutiple instances of nav 'prev-next'. All target different anchors. All are within the same html page.

<nav class="prev-next">
    <a href="#video-wrapper" class="prev">Prev</a>
</nav>

Upvotes: 3

Views: 12025

Answers (4)

Hari Pachuveetil
Hari Pachuveetil

Reputation: 10374

You don't need .each() for binding event handlers. Try this instead:

$('.next, .prev').click(function(e){
        var target = $(this).attr('href');
        initiateScroll(target);
        console.log("click!");
        e.stopPropagation();
        e.preventDefault();
        return false;
});

EDIT: I think it is the way you are attaching the event handler from within the setupHorzNav function that is causing it. Change it to attach it only once from say, $(document).ready() or something.

I have managed to get the situation of multiple event handlers by attaching the event handlers from a function that gets called from event handler. The effect is that the number of click event handlers keeps increasing geometrically with each click.

This is the code: (and the jsfiddle demo)

function setupNav() {
    $('.next, .prev').each(function () {
        $(this).click(function (e) {
            setupNav();
            var target = $(this).attr('href');
            console.log("click!");
            e.stopPropagation();
            e.preventDefault();
            return false;
        });
    });
}

setupNav();

See how calling the setupNav() function from the click event handler adds multiple eventhandlers (and the click log message) on successive clicks

Upvotes: 5

ieeehh
ieeehh

Reputation: 674

Are there no other click bindings elsewhere?

Are you loading the page with ajax?

You could also try this:

$('.next, .prev').click(function (e) {
    var target = $(this).attr('href');
    initiateScroll(target);
    console.log("click!");
    e.stopPropagation();
    e.preventDefault();
    return false;
});

Upvotes: 1

techfoobar
techfoobar

Reputation: 66663

Since it is not clear from your question whether you are calling the binding function multiple times, a quick and dirty fix would be:

$('.next, .prev').unbind('click').click(function() {
    ...
});

What you are doing here is unbinding any previously bound event handlers for click and binding afresh.

Upvotes: 3

Fraz Sundal
Fraz Sundal

Reputation: 10448

Try unbinding the click event like this

$(this).unbind('click').click(function (e) {    
});

Upvotes: 8

Related Questions