Abhishek Sinha
Abhishek Sinha

Reputation: 5123

jquery function being called too many times even after using $(this)

With JSON data received from ajax success event I use this data to make dynamic html stuffs, something like this

function loop_json(data) {
    var response_data = jQuery.parseJSON(data);
    var vip_userId = $('#userId').val();
    $(response_data.vip_poll).each(function(index, value) {
        var t= '';
        t += '<li class="vip-polls-holder" id="'+value.id+'">';
        t += '<div class="user-img">';
        t += '<a href="users.php?user_name='+response_data.vip_pollOwners[index].user_name+'"><img src="'+response_data.vip_pollOwners[index].user_avatar+'" class="user-img-pic img-circle" /></a>';
        t += '</div>';
...
t +='</li>';
$('.vip-polls-holder-ul-mainDIV').append(t);
// And so I attach some functions with these li boxes such as
function1();
function2(); //and
VIP_dNd_multiple();
   });
}

Where VIP_dNd_multiple() is->

function VIP_dNd_multiple() {

// let it be called part a
$trashVIP.each(function() {
    $(this).droppable({
        accept: "#VIPgalleryMulitple"+$(this).attr('id')+" > li",
        activeClass: "ui-state-highlight",
        drop: function (event, ui) {
            console.log('abc');  //This prints one time
        }
    });
});   

// let it be called part b
$("ul.VIPgalleryMulitple > li").each(function() {

        var $item = $(this);
        $item.click(function (event) {
            event.preventDefault();
            console.log('ok');  //This prints multiple times
        });
    });
}

The problem is VIP_dNd_multiple() is called as many times as there are li elements present on DOM and hence console gives 'ok' (part b of the function) as output multiple times which is undesirable, of course. I don't understand when I'm using click event on $(this) li why all the li elements are firing console.log action?
Surprisingly, part a of the same function is outputing console correctly just once.

Upvotes: 0

Views: 508

Answers (3)

Abhishek Sinha
Abhishek Sinha

Reputation: 5123

I removed $.each function as it was perhaps the root of the problem. Instead I switched to 'on' method. Further, I removed the id of the anchor element after first click to discard further event after first click. My final solution combining A. Rossi answer ->

$("ul.VIPgalleryMulitple > li").on('click', function (event) {

        if (event.handled !== true) {
            event.handled = true;

            var $item = $( this ),

            var ids = $(this).attr('id');

            console.log('ok'); 

            $(this).find('a').removeAttr('id');
        }
        return false;
    });

Upvotes: 0

denchu
denchu

Reputation: 869

What is the value of $TrashVIP? It seems like it doesn't pass in the LI items, rather, it's reading the UL item which is only one, so that's why it will print one time.

The second function calls for each LI item, so if you have 10 LI items, and you click on one of the LI it will indeed pass through the loop and render the OK as many times.

It seems to me you don't really need the second each function, rather, just put the click function as is, and it will already be triggered once any of the LI item is clicked.

$("ul.VIPgalleryMulitple > li").click(function() {
    event.preventDefault();
    console.log("ok"); 
});

Sample Fiddle

Upvotes: 1

Jax Teller
Jax Teller

Reputation: 1467

I don't know if it can help for this, but this code save me many times for prevent multiple event :

$item.click(function (event) {
    event.preventDefault();
    if (event.handled !== true) {
        event.handled = true;
        //Your stuff
        console.log("ok");
    }
})

Upvotes: 0

Related Questions