[英]JavaScript event is being fired twice when event has only happened once
我一直在研究一个小的JavaScript库,该库用于处理简单的触摸事件,例如点击和滑动。 我暂时将其放置在GitHub上。
如果您查看thumb.html ,您可以看到我如何使用我的库。
//JavaScript portion
//Assign the tap event to all elements with specific classname
thumb.get('.swipearea').on('tap', function(e) {
console.log('The event "' + e.detail.name + '" occured.')
})
//Assign the swipeleft event by ID
thumb.get('#a1').on('swipeleft', function(e) {
console.log('The event "' + e.detail.name + '" occured.')
})
正如您从HTML文件中看到的那样,我为所有名称为“ swipearea”的元素分配了“ tap”。 但是,我只想向具有相同类名的一个元素添加“ swipeleft”事件,因此我使用该元素的ID附加了该事件。
这在大多数情况下都是有效的。 问题是,当我点击带有两个事件的元素时,它将消息记录两次。 向左滑动时,它还会记录两次。 但是,当我点击另一个只分配了“ tap”的元素时,它一次正确地登录到控制台。
我是否错误地创建了每个实例? 我试图在thumb实例之外创建一个方法,但这导致了相同的行为。
如何消除这种行为?
有关控制台日志的更多信息
当我在ID为a1
的元素上点击一次时,我得到The event "Tap" occurred.
登录到控制台两次。
当我在ID为a1
的元素上The event "Swipe Left" occurred.
我得到The event "Swipe Left" occurred.
登录到控制台两次。
当我在ID为a2
的元素上点击一次时,我得到The event "Tap" occurred.
1次登录到控制台。
您的代码的结构很有可能会使得侦听器被添加两次。 我们需要查看更多代码才能确定。
在某些环境中,将不再添加与上一个监听器完全匹配的监听器(在===
意义上)(本机addEventListener
API也是这种情况)。 我不知道jQuery是否是这种情况。 要尝试此操作,可以将侦听器定义为单独的函数:
function listener(e) {
console.log('The event "' + e.detail.name + '" occured.');
}
然后将其添加为
thumb.get('.swipearea').on('tap', listener);
您可能会问,即使我在源代码中添加了两次侦听器,侦听器函数代码也完全相同,这并不意味着该函数是相同的,因此不会将其添加为重复项。听众? 好吧,不。 如果该函数在其他函数中定义,则每次都会是“不同”函数。 考虑以下:
function am_i_the_same() {
return function() {return 42;};
}
am_i_the_same() === am_i_the_same(); // false
如果您在面向对象的环境中工作,则可以执行以下操作
my_object = {
tap_listener: function(e) {
console.log('The event "' + e.detail.name + '" occurred.');
},
set_listener: function() {
thumb.get('.swipearea').on('tap', this.tap_listener);
}
};
但是,例如,在执行this.tap_listener.bind(this)
那一刻,您现在每次调用时都有一个不同的函数,因此将导致重复的侦听器。
首先,我不会预先构建您的自定义事件。 每当您需要发射它时,我都会创建一个新的。 否则,您可能会与时间戳,目标元素和传播设置发生奇怪的冲突。
说到传播设置,最好在所有触摸事件上立即停止传播。
接下来,这可能是个人喜好,但我不会像您那样建立多元素支持。 所有这些循环以及forEach和maps会使您的代码复杂化。 只需编写一个组件即可完成一项任务,即管理触摸,而不是完成两项任务,即管理触摸和管理元素组。
我很好奇为什么在全局范围而不是在使用它们的函数中声明像distanceX
这样的变量。
至于您的特定问题,我看不到为什么发生,但是我会尝试在thumb.js的第112行添加else
,并查看是否出于某种原因构造了if语句以便允许tap和swipe事件被省略。
我想您知道那里有图书馆以此为生。 他们将在许多小细节上做得更好,例如在touchstart不在应用程序区域之外时,诸如touchend的边缘情况就会出现在您的元素上,等等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.