Javascript 每次调用弹出窗口时,jQuery/js都存储/追加变量,但为什么呢?

Javascript 每次调用弹出窗口时,jQuery/js都存储/追加变量,但为什么呢?,javascript,jquery,Javascript,Jquery,我有一个弹出窗口,当调用它时,它会得到一个变量(userid),当我在弹出窗口中选择某个内容时,我会将该变量赋给函数。 每次的第一个变量都是新的,这就是它应该是什么样子。 但是第二个变量追加并包含上次调用弹出窗口时的所有值。 但我为什么以及如何防止这种情况? JS代码: $(".class").click(function() { var userid = $(this).attr('id'); $(".popup").toggle(); console.lo

我有一个弹出窗口,当调用它时,它会得到一个变量(userid),当我在弹出窗口中选择某个内容时,我会将该变量赋给函数。

每次的第一个变量都是新的,这就是它应该是什么样子。
但是第二个变量追加并包含上次调用弹出窗口时的所有值。

但我为什么以及如何防止这种情况?

JS代码:

$(".class").click(function() {
    var userid    = $(this).attr('id');
    $(".popup").toggle();
    console.log('first');
    console.log(userid);

    $(".popup td").click(userid,function() {
        console.log('second');
        console.log(userid);

        $(".popup").hide();
    });
});



控制台读数:

"first"
"1"
"second"
"1"

"first"
"2"
"second"
"1"
"2"

"first"
"3"
"second"
"1"
"2"
"3"

主要问题是,对于每次单击
.class
元素,您都会为单击
.popup td
元素添加一个新的事件处理程序。因此:

第一次点击:

"first" "1" "second" "1" 还有意义:您第二次单击(显然是在
2
上),因此
.class
处理程序显示
2
,并将新的事件处理程序绑定到将接收
2
弹出td
。然后,当您单击
.popup td
元素时,它会激发分配给它的两个处理程序(按照它们被分配的顺序),因此您会看到
1
后面跟着
2

(然后同样的事情第三次发生,依此类推……)

如果您打算替换处理程序,可以这样做:

$(".class").click(function() {
    var userid    = $(this).attr('id');
    $(".popup").toggle();
    console.log('first');
    console.log(userid);

    $(".popup td").off("click.foo").on("click.foo", userid, function() {
        console.log('second');
        console.log(userid);

        $(".popup").hide();
    });
});
在附加新的处理程序之前,删除任何以前的
click.foo
处理程序

然而,我不会像那样连接和分离处理程序。相反,只需让
.class
处理程序设置一个变量,即(一个)
.popup td
处理程序可以使用:

var clickedUserId;                         // Declare it outside either handler
$(".class").click(function() {
    clickedUserId    = $(this).attr('id'); // Set it here
    $(".popup").toggle();
    console.log('first');
    console.log(clickedUserId);
});
$(".popup td").click(function() {
    console.log('second');
    console.log(clickedUserId);            // Use it here

    $(".popup").hide();
});

为了完整性:我不会将
clickedUserId
设为全局名称空间,全局名称空间已经非常拥挤,只需在两个事件处理程序共享的范围内声明它即可。如果您手头还没有范围,请将上述内容包装在立即调用的函数表达式(IIFE)中:


不要将事件处理程序放在另一个事件处理程序中。
var clickedUserId;                         // Declare it outside either handler
$(".class").click(function() {
    clickedUserId    = $(this).attr('id'); // Set it here
    $(".popup").toggle();
    console.log('first');
    console.log(clickedUserId);
});
$(".popup td").click(function() {
    console.log('second');
    console.log(clickedUserId);            // Use it here

    $(".popup").hide();
});
(function() {
    var clickedUserId;                         // Declare it outside either handler
    $(".class").click(function() {
        clickedUserId    = $(this).attr('id'); // Set it here
        $(".popup").toggle();
        console.log('first');
        console.log(clickedUserId);
    });
    $(".popup td").click(function() {
        console.log('second');
        console.log(clickedUserId);            // Use it here

        $(".popup").hide();
    });
})();