简体   繁体   中英

jquery aggregates onclick on div

I have a div where I on pageload binds a click function like below

 <div class="document-short-list-item" data-d-id="5" data-w-id="16" data-s-id="15">Klik her for at tilføje</div>

$(".document-short-list-item").click(function () {
    addToShortList(this);
});

The addToShortList performs the following:

  $(element).removeClass('document-short-list-item').addClass('document-short-list-item-added').on('click', removefromShortList(element));

and the removefromShortList reverses the same

 $(element).removeClass('document-short-list-item-added').addClass('document-short-list-item').on('click', addToShortList(element));

The problem is that the above code aggregates on each click, this means the both addToShortList and removeFromShortList runs multiple times on click

Because every click event calls another .on() to add more handlers.

It's almost always a bad idea to bind/unbind handlers in their own binding events and often leads to this kind of situation. Instead, you can rely on the functionality of .on() to dynamically execute as the classes change. This is called "event delegation".

Basically bind the click event to a common parent element ( document often works, unless anything is stopping the event propagation). Something like this:

$(document).on("click", ".document-short-list-item", function () {
    $(this)
        .removeClass("document-short-list-item")
        .addClass("document-short-list-item-added");
});
$(document).on("click", ".document-short-list-item-added", function () {
    $(this)
        .removeClass("document-short-list-item-added")
        .addClass("document-short-list-item");
});

This will attach the click handler to the document itself, but when handling that click it will filter the originating element by the selector argument. So any originating .document-short-list-item will invoke the first handler, and any originating .document-short-list-item-added will invoke the second handler. This way you only need to set these handlers once on page load and they internally filter as needed.


Alternatively, if this approach might work in your situation, you can use a single handler which will simply toggle the classes. For example:

$(document).on("click", ".document-short-list-item, .document-short-list-item-added", function () {
    $(this)
        .toggleClass("document-short-list-item")
        .toggleClass("document-short-list-item-added");
});

Which would respond to either originating element (since both are in the selector) and toggle both classes, regardless of which one is currently active.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM