封装在函数中的JavaScript事件侦听器
我有一个函数中的事件侦听器。侦听器和发射器都在同一个函数中 触发事件时,变量将递增。到现在为止,一直都还不错。但是,当我多次调用该函数时,侦听器在同一个函数调用中会被触发数次封装在函数中的JavaScript事件侦听器,javascript,javascript-events,Javascript,Javascript Events,我有一个函数中的事件侦听器。侦听器和发射器都在同一个函数中 触发事件时,变量将递增。到现在为止,一直都还不错。但是,当我多次调用该函数时,侦听器在同一个函数调用中会被触发数次 var test = function() { var completeStatus = 0; $(document).on('gt', function() { console.log(++completeStatus); }); $(document).trig
var test = function() {
var completeStatus = 0;
$(document).on('gt', function() {
console.log(++completeStatus);
});
$(document).trigger('gt');
}
test();
test();
test();
当函数被调用三次时,它期望输出1三次。但它输出:
0
1.
0
2.
一,
这是为什么?如何获得期望的行为
这里有一个可以尝试的方法。添加了事件列表,它不会取代以前的列表:
将一个或多个事件的事件处理程序函数附加到
选定的元素
当一个元素有多个事件侦听器时,顺序定义得很好:
绑定到元素的事件处理程序的调用顺序与
他们被绑住了
然后按这个顺序执行它们:
执行附加到匹配元素的所有处理程序和行为
对于给定的事件类型
所以,
test
时,添加一个completeStatus=0
的事件侦听器,并触发它。所以你得到了
0
1 // From the first event listener
0 // From the second event listener
2 // From the first event listener
1 // From the second event listener
0 // From the third event listener
test
,前一个事件侦听器具有completeStatus=1
。然后添加第二个事件侦听器,并使用completeTestatus=0
,然后触发这两个事件。所以你得到了
0
1 // From the first event listener
0 // From the second event listener
2 // From the first event listener
1 // From the second event listener
0 // From the third event listener
test
,第一个事件侦听器具有completeStatus=2
,第二个事件侦听器具有completeStatus=1
。然后添加第三个事件监听器,其completeTestatus=0
,并将它们全部触发。所以你得到了
0
1 // From the first event listener
0 // From the second event listener
2 // From the first event listener
1 // From the second event listener
0 // From the third event listener
test
时,添加一个completeStatus=0
的事件侦听器,并触发它。所以你得到了
0
1 // From the first event listener
0 // From the second event listener
2 // From the first event listener
1 // From the second event listener
0 // From the third event listener
test
,前一个事件侦听器具有completeStatus=1
。然后添加第二个事件侦听器,并使用completeTestatus=0
,然后触发这两个事件。所以你得到了
0
1 // From the first event listener
0 // From the second event listener
2 // From the first event listener
1 // From the second event listener
0 // From the third event listener
test
,第一个事件侦听器具有completeStatus=2
,第二个事件侦听器具有completeStatus=1
。然后添加第三个事件监听器,其completeTestatus=0
,并将它们全部触发。所以你得到了
0
1 // From the first event listener
0 // From the second event listener
2 // From the first event listener
1 // From the second event listener
0 // From the third event listener
0 //from first function call
1 0 //from second function call
2 1 0 //frm third function call
.... and so on
解决方案:
var test = function() {
var completeStatus = 0;
var pageInitialized = false;
$(document).on('gt', function() {
if(pageInitialized) return;
console.log(++completeStatus);
pageInitialized = true;
});
$(document).trigger('gt');
}
test();
test();
test();
因为您使用的是$(document.trigger('gt');所以它在所有文档事件中都启动了触发器事件,这就是为什么增加函数调用以返回输出的原因
0 //from first function call
1 0 //from second function call
2 1 0 //frm third function call
.... and so on
解决方案:
var test = function() {
var completeStatus = 0;
var pageInitialized = false;
$(document).on('gt', function() {
if(pageInitialized) return;
console.log(++completeStatus);
pageInitialized = true;
});
$(document).trigger('gt');
}
test();
test();
test();
如上面回复中所述,
.on()
添加了事件侦听器,因此在您的示例中,它添加了3次
除了前面的答案之外,最好避免添加多个侦听器,因为如果无法删除它们,可能会导致内存泄漏。因此,您可以尝试此解决方案,在再次添加之前删除事件侦听器
var test = function() {
var completeStatus = 0;
var GT_EVT = 'gt';
$(document).off(GT_EVT).on(GT_EVT, function() {
console.log(++completeStatus);
});
$(document).trigger(GT_EVT);
}如上述回复中所述,
.on()
添加了事件侦听器,因此在您的示例中添加了3次
除了前面的答案之外,最好避免添加多个侦听器,因为如果无法删除它们,可能会导致内存泄漏。因此,您可以尝试此解决方案,在再次添加之前删除事件侦听器
var test = function() {
var completeStatus = 0;
var GT_EVT = 'gt';
$(document).off(GT_EVT).on(GT_EVT, function() {
console.log(++completeStatus);
});
$(document).trigger(GT_EVT);
}另一种方法是在每次执行函数时生成唯一的事件和处理程序:
var test = function() {
var completeStatus = 0;
var uniqid = Math.random().toString(36).slice(-8);
$(document).on('gt' + uniqid, function() {
console.log(++completeStatus);
});
$(document).trigger('gt' + uniqid);
}
test();
test();
test();
但是性能影响呢?使用这种方法有什么优点/缺点吗?另一种方法是在每次执行函数时生成唯一的事件和处理程序:
var test = function() {
var completeStatus = 0;
var uniqid = Math.random().toString(36).slice(-8);
$(document).on('gt' + uniqid, function() {
console.log(++completeStatus);
});
$(document).trigger('gt' + uniqid);
}
test();
test();
test();
但是性能影响呢?使用这种方法有什么优点/缺点吗?每次调用
test
,它都会在事件gt
上绑定一个侦听器,并向绑定的所有侦听器触发一个gt
事件。(不仅仅是您之前创建的一个)您更容易理解,只需简短地检查控制台:每次都会创建侦听器,每个侦听器都有自己的completeStatus
变量,因此只需假设您有多个订阅者。请注意,在您的问题中,您有++completeStatus
,它产生1232 1
,在你的小提琴中有completeStatus++
,它产生0102 1 0
。每次你调用test
,它会在事件gt
上绑定一个监听器,并向绑定的所有监听器触发gt
事件。(不仅仅是您之前创建的一个)您更容易理解,只需简短地检查控制台:每次都会创建侦听器,每个侦听器都有自己的completeStatus
变量,因此只需假设您有多个订阅者。请注意,在您的问题中,您有++completeStatus
,它产生了12321
,在你的小提琴里有CompleteTastus++
,它产生了0101010
。非常好用,谢谢!我还可以在触发事件侦听器后立即使用$(document.off
解除其绑定。因此,在给定的时间只有一个事件侦听器。非常有效,谢谢!我还可以使用$(document.off)解除事件侦听器的绑定