gpt4 book ai didi

当事件只发生一次时,JavaScript 事件被触发两次

转载 作者:行者123 更新时间:2023-11-30 17:28:24 24 4
gpt4 key购买 nike

我一直在开发一个小型 JavaScript 库,用于处理简单的触摸事件,例如点击和滑动。我暂时放在了GitHub上。

See it here: thumb.js - Repository

如果你看一下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”的所有元素。但是,我只想将“swipeleft”事件添加到具有相同类名的一个元素,因此我使用该元素的 ID 附加了该事件。

这在大多数情况下都有效。问题是,当我点击附加了两个事件的元素时,它会记录消息两次。向左滑动时它也会记录两次。但是,当我点击另一个只分配了“tap”的元素时,它会正确地记录到控制台一次。

我是否错误地创建了每个实例?我试图在 thumb 实例之外创建一个方法,但这导致了相同的行为。

如何消除这种行为?

关于控制台日志的更多信息

当我在 ID 为 a1 的元素上点击一次时,我得到 The event "Tap"occurred. 记录到控制台 2 次。

当我在 ID 为 a1 的元素上“向左滑动”时,我得到了 The event "Swipe Left"occurred. 记录到控制台 2 次。

当我在 ID 为 a2 的元素上点击一次时,我得到了 The event "Tap"occurred. logged to the console one 1 time.

最佳答案

很可能您的代码结构使得监听器被添加了两次。我们需要查看更多您的代码才能确定。

在某些环境中,不会再次添加与前一个监听器(在 === 意义上)完全匹配的监听器( native 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 和映射会使您的代码复杂化。只需编写一个只做一件事的组件,即管理触摸,而不是两件事,即管理触摸和管理元素组。

我很好奇为什么要声明像 distanceX 这样的变量在全局范围内而不是在使用它们的函数中。

至于你的具体问题,我不明白为什么会这样,但我会尝试添加一个 else在 thumb.js 的第 112 行,看看是否出于某种原因构建了您的 if 语句,以便允许省略点击和滑动事件。

我假设您知道有一些图书馆以此为生。他们将在许多小细节上做得更好,包括边缘情况,例如当 touchstart 在您的应用程序区域之外时 touchend 到达您的元素等。

关于当事件只发生一次时,JavaScript 事件被触发两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23728944/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com