最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery click event triggered multiple times off one click - Stack Overflow

programmeradmin2浏览0评论

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>

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>
Share Improve this question edited Jul 11, 2017 at 14:17 freeMagee asked Feb 13, 2013 at 14:44 freeMageefreeMagee 4642 gold badges6 silver badges19 bronze badges 9
  • 2 Can you post where you're calling setupHorzNav from and the code surrounding <nav class="prev-next">? – Michael Marr Commented Feb 13, 2013 at 14:48
  • 1 Well just a few suggestions. You don't need to use each in this scenario, just use: $('.next, .prev').click(function (e) { //... });. And you don't need to use all three of e.stopPropagation();, e.preventDefault(); and return false;. return false; automatically does the preventDefault and stopPropagation. Those are useful if you only want to do one of them, or want to execute it sooner than return false because of possible problems in your code – Ian Commented Feb 13, 2013 at 14:48
  • Also, it is better to define your event handler function outside a loop (such as each in your case), to make sure you do not have multiple instances of the same function in memory. – techfoobar Commented Feb 13, 2013 at 14:50
  • 3 I believe chrome also shows 16 logs but as a digit in front of the line. – TheBrain Commented Feb 13, 2013 at 14:53
  • 1 Put a console.log right at the start of your setupHorzNav function and check how many times it is getting called. – techfoobar Commented Feb 13, 2013 at 14:55
 |  Show 4 more comments

4 Answers 4

Reset to default 8

Try unbinding the click event like this

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

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

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.

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;
});
发布评论

评论列表(0)

  1. 暂无评论