Jquery multiple click binding not working correctly

I seem to have a problem making copies of the template and binding the .click () method to them. Take the following javascript for example:

function TestMethod() {
    var test = Array();
    test[0] = 0;
    test[1] = 1;
    test[2] = 2;

    // Insert link into the page
    $("#test_div").html("<a href=\"#\"></a><br>");
    var list;
    for (x = 0; x < test.length; x++) {
        var temp = $("#test_div").clone();
        temp.find('a').html("Item #" + test[x]);
        temp.click(function () { alert(x); });

        if (list == undefined)
            list = temp;
        else
            list = list.append(temp.contents());
    }
    $("#test_div2").append(list);
 }

      

The problem I see with is that no matter what element the user clicks on, it always fires an alert (2), even when you click on the first few elements.

How can I get this to work?

Edit: I made a very simple example that should make the problem much clearer. No matter which item you click on, it always displays an alert box with the number 2 on it.

+2


a source to share


2 answers


Correct me if I'm wrong, .valueOf()

in JS it returns a primitive boolean object value .....

it won't happen ShowObject(5,'T');

...ShowObject(objectVal.valueOf(), 'T');

Why not use it objects[x].Value

directly?ShowObject(objects[x].Value, 'T');

WOOOOOSSSHHHH!



after deep searching ... I found a solution ...

because it's a closure, it won't actually work ...
here's the solution,

temp.find('a').bind('click', {testVal: x},function (e) { 
   alert(e.data.testVal);
   return false;
});

      

for a better explanation, read this ... in the middle of the page where it says Passing event data a
quick demo of the above code

+1


a source


I think your question comes from a misunderstanding of scopes in JavaScript. (My apologies if I am wrong.)

function () {
    for (...) {
        var foo = ...;

        $('<div>').click(function () { alert(foo); }).appendTo(...);
    }
}

      

In JavaScript, functions only create a new scope (usually called a closure ).

So every loop of the loop for

will know the same foo

as its scope is that function

and not for

. This also applies to defined events. At the end of the cycle, everyone click

will know the same ones foo

and know that this is the last value it was assigned.

To work around this, either create an inner closure with an instantly executable anonymous function:

function () {
    for (...) {
        (function (foo) {
            $('<div>').click(function () { alert(foo); }).appendTo(...);
        })(...);
    }
}

      



Or, using a callback based function such as jQuery.each

:

function () {
    $.each(..., function (i, foo) {
        $('<div>').click(function () { alert(foo); }).appendTo(...);
    });
}

      


For your problem, I would go with the latter (note the changes objects[x]

on object

):

var list;
jQuery.each(data.objects, function (x, object) {

    // Clone the object list item template
    var item = $("#object_item_list_template").clone();

    // Setup the click action and inner text for the link tag in the template
    var objectVal = object.Value;
    item.find('a').click(function () { ShowObject(objectVal.valueOf(), 'T'); }).html(object.Text);

    // add the html to the list
    if (list == undefined)
        list = item;
    else
        list.append(item.contents());
});

      

+1


a source







All Articles