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

时间:2014-05-19 02:33:37

标签: javascript

我一直在开发一个小型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文件中看到的那样,我正在分配一个" tap"对于名称为" swipearea"的所有元素。但是,我想添加一个" swipeleft" event只有一个具有相同类名的元素,所以我使用元素ID附加了事件。

这在很大程度上是有效的。问题是,当我点击附加了两个事件的元素时,它会将消息记录两次。向左滑动时它也会记录两次。但是,当我点击另一个只有"点击"已分配,它会正确登录到控制台一次。

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

如何消除此行为?

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

当我点击ID为a1的元素时,我会The event "Tap" occurred. 2次登录到控制台。

当我" swipeleft"在ID为a1的元素上,我将The event "Swipe Left" occurred.登录到控制台2次。

当我点击ID为a2的元素时,我会The event "Tap" occurred.一次登录到控制台。

1 个答案:

答案 0 :(得分:2)

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

在某些环境中,不会再次添加与前一个侦听器(===意义上的)完全匹配的侦听器(本地addEventListener API也是如此)。我不知道jQuery是否属于这种情况。要尝试此操作,您可以将侦听器定义为单独的函数:

function listener(e) {
    console.log('The event "' + e.detail.name + '" occured.');
}

然后将其添加为

thumb.get('.swipearea').on('tap', listener);

你可能会问,即使我在原始代码中添加了两次监听器,监听器功能代码完全相同,这并不意味着功能是相同的,所以它赢了& #39;是否作为重复的听众添加?好吧,不。如果函数是在一些其他函数中定义的,那么它将是一个不同的"每次都有功能。请考虑以下事项:

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)时,您现在每次调用时都会有不同的功能,因此会产生重复的侦听器。

更新

首先,我不会预先构建您的自定义事件。每次你需要发射它时我都会创建一个新的。否则,您可能会遇到与时间戳,目标元素和传播设置的奇怪冲突。

说到传播设置,最好立即停止所有触摸事件的传播。

接下来,这可能是个人偏好,但我不会像你一样构建多元素支持。它使您的代码与所有这些循环以及每个映射和映射相混淆。只需编写一个可以完成一件事的组件,即管理触摸,而不是两件事,即管理触摸和管理元素组。

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

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

我假设你知道有些图书馆以此为生。他们将在许多小细节上做得更好,包括边缘情况,例如当触摸开始在你的应用领域之外时,你的元素会出现问题,等等。