2

在创建模板副本并将 .click() 方法正确绑定到它们时,我似乎遇到了问题。以下面的 javascript 为例:

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);
 }

我看到的问题是,无论用户单击哪个项目,它总是运行警报(2),即使您单击前几个项目也是如此。

我怎样才能让它工作?

编辑:我做了一个非常简单的例子,应该更清楚地显示问题。无论您点击什么项目,它总是会显示一个带有数字 2 的警告框。

4

2 回答 2

1

我认为您的问题源于对 JavaScript 范围的误解。(如果我错了,我很抱歉。)

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

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

在 JavaScript 中,只有函数会创建一个新的作用域(通常称为闭包)。

因此,循环的每一轮都for将知道相同的foo,因为它的范围是function,而不是for。这也适用于正在定义的事件。在循环结束时,每个人都click将知道相同的foo内容并知道它是最后一个分配的值。

为了解决这个问题,可以使用立即执行的匿名函数创建一个内部闭包:

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

或者,使用基于回调的函数,例如jQuery.each

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

对于您的问题,我会选择后者(注意objects[x]对 just的更改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());
});
于 2010-05-14T06:47:03.587 回答
1

如果我错了,请纠正我,.valueOf()在 JS 中返回布尔对象的原始值.....

这不会发生ShowObject(5,'T');......ShowObject(objectVal.valueOf(), 'T');

为什么不objects[x].Value直接使用?ShowObject(objects[x].Value, 'T');

呜呜呜呜!

经过深入搜索...我找到了解决方案...

因为它是一个闭包,它不会真的那样工作......
这是一个解决方案,

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

为了得到最好的解释,请阅读这个......在页面的中间部分,它说传递事件数据
是上述代码的快速演示

于 2010-05-14T04:57:28.130 回答