绑定多个副本时,Jquery 单击绑定无法正常工作

发布于 2024-09-02 04:37:57 字数 803 浏览 5 评论 0原文

在创建模板副本并将 .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);
 }

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

我怎样才能让它发挥作用?

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

I seem to have an issue when creating copies of a template and tying the .click() method to them properly. 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 am seeing with this is that no matter which item the user clicks on, it always runs alert(2), even when you click on the first few items.

How can I get this to work?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清浅ˋ旧时光 2024-09-09 04:37:57

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

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

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

WOOOOOSSSHHHH!

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

因为它是一个闭包,所以它赢了真的不是这样工作的...
这是一个解决方案,

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

为了获得最佳解释,请阅读此内容...在页面的中间部分其中显示传递事件数据
上述内容的快速演示代码

Correct me if I'm wrong, .valueOf() in JS returns the primitive value of a Boolean object.....

this would not happen ShowObject(5,'T');... ShowObject(objectVal.valueOf(), 'T');

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

WOOOOOSSSHHHH!

after searching deeply... I found a solution...

because it's a closure, it won't really work that way...
here's a solution,

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

for best explanation, please read this... in the middle part of the page where it says Passing Event Data
a quick demo of above code

旧人九事 2024-09-09 04:37:57

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

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

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

在 JavaScript 中,只有函数才能创建新作用域(通常称为闭包)。

因此,每轮 for 循环都会知道相同的 foo,因为它的作用域是 function,而不是 for.这也适用于正在定义的事件。在循环结束时,每次点击都会知道相同的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] 的更改只是对象):

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

I think your issue arises from a misunderstanding of scopes in JavaScript. (My apologies if I'm wrong.)

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

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

In JavaScript, only functions create a new scope (commonly referred to as a closure).

So, every round of the for loop will know the same foo, since its scope is the function, not the for. This also applies to the events being defined. By the end of looping, every click will know the same foo and know it to be the last value it was assigned.

To get around this, either create an inner closure with an immediately-executing, 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 issue, I'd go with the latter (note the changes of objects[x] to 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());
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文