Events 如何定义更改具有不同事件的元素的事件?

Events 如何定义更改具有不同事件的元素的事件?,events,mootools,Events,Mootools,为这个模糊的标题道歉,很难用一句话来解释 在任何情况下,假设我有一个按钮,其动作由数据动作属性定义。当用户单击所述按钮时,会发生一些事情,按钮的动作将更改为第二种状态 然而,实现这一点后,我发现为第二个状态定义的事件会在触发第一个状态后自动运行,就好像“单击”在函数调用之后持续并触发第二个事件一样 一次单击应该显示日志“转换为“foo”,第二次单击应该显示日志“转换为“bar”,但是如果您尝试,您将看到两个事件都被触发 我怎样才能阻止这一切 编辑:感谢Dimitar的帮助- var actio

为这个模糊的标题道歉,很难用一句话来解释

在任何情况下,假设我有一个按钮,其动作由
数据动作
属性定义。当用户单击所述按钮时,会发生一些事情,按钮的动作将更改为第二种状态

然而,实现这一点后,我发现为第二个状态定义的事件会在触发第一个状态后自动运行,就好像“单击”在函数调用之后持续并触发第二个事件一样

一次单击应该显示日志“转换为“foo”,第二次单击应该显示日志“转换为“bar”,但是如果您尝试,您将看到两个事件都被触发

我怎样才能阻止这一切

编辑:感谢Dimitar的帮助-

var action = ((this.retrieve('action', 'foo') != this.getProperty('data-action')) ? 'bar' : 'foo' );
if (action == 'foo') {
    console.log('executing "foo"');
    this.store('action', 'bar');
}
else {
    console.log('executing "bar"');
    this.store('action', 'foo');
}
好情况:)

我看到更改事件处理程序声明的顺序可以解决第一次单击时的问题(并推迟到下一次)

而且,我认为Mootools没有问题:单击按钮,事件将DOM冒泡到主体,主体检查其所有附加事件(在您的情况下是委派的),并首先停止,因为它找到了与
[data action=“bar”]
匹配的事件。并执行相关功能。主体现在继续检查其他委托匹配(它没有理由停止!),并再次找到第二个
[data action=“foo”]
匹配

如果不使用一些标志/状态变量或延迟函数执行,恐怕无法避免这种情况。我认为最后一个是最好的,或者至少是最简洁的解决方案(如果适用,我不知道延迟是否会给您带来问题)。如果函数执行延迟了一点(毫秒),那么只需跳过委派事件检查。演示

不错的情况:)

我看到更改事件处理程序声明的顺序可以解决第一次单击时的问题(并推迟到下一次)

而且,我认为Mootools没有问题:单击按钮,事件将DOM冒泡到主体,主体检查其所有附加事件(在您的情况下是委派的),并首先停止,因为它找到了与
[data action=“bar”]
匹配的事件。并执行相关功能。主体现在继续检查其他委托匹配(它没有理由停止!),并再次找到第二个
[data action=“foo”]
匹配


如果不使用一些标志/状态变量或延迟函数执行,恐怕无法避免这种情况。我认为最后一个是最好的,或者至少是最简洁的解决方案(如果适用,我不知道延迟是否会给您带来问题)。如果函数执行延迟了一点(毫秒),那么只需跳过委派事件检查。Demo

正如lorenzo所说,当您委派它并更改用作委派标识符的属性时,我觉得这听起来像是一种反模式。我认为增加延迟也不是一个好模式

或者使用您在元素上更改的第二个属性,或者更好的做法是,在初始事件从属性读取状态后,更改保持元素存储中状态的var以提高性能

$(document.body).addEvents({
    'click:relay([data-action=foo])': function() {
        this.store("action", ((this.retrieve("action") || this.get("data-action")) === 'foo') ? 'bar' : 'foo');
        this.set("html", 'State + ' + this.retrieve("action"));
    }
});

就像lorenzo说的,当你委派它并更改属性(用作委派标识符)时,我觉得这听起来像是一种反模式。我认为增加延迟也不是一个好模式

或者使用您在元素上更改的第二个属性,或者更好的做法是,在初始事件从属性读取状态后,更改保持元素存储中状态的var以提高性能

$(document.body).addEvents({
    'click:relay([data-action=foo])': function() {
        this.store("action", ((this.retrieve("action") || this.get("data-action")) === 'foo') ? 'bar' : 'foo');
        this.set("html", 'State + ' + this.retrieve("action"));
    }
});

谢谢你逐步解决这个问题。我现在可以更好地想象正在发生的事情。我最初也考虑引入一个延迟,虽然它看起来像是一个创可贴解决方案,我只是问了一下,以防有一个更优雅的解决方案。谢谢你的帮助!谢谢你逐步解决这个问题。我现在可以更好地想象正在发生的事情。我最初也考虑引入一个延迟,虽然它看起来像是一个创可贴解决方案,我只是问了一下,以防有一个更优雅的解决方案。谢谢你的帮助!有趣的是,我从未想过使用元素存储(或者更确切地说,我从未使用过元素存储)。我会就此回复你的…谢谢你的代码片段,迪米特尔。我似乎已经让它工作得很好了。我将更新问题以反映新的代码。我的最后一个问题是-为什么您使用
$(document.body)
而不是简单地使用
document.body
?我的印象是,
$()
试图通过读取整个页面来查找相关元素,而DOM…IE中已经定义了
document.body
。IE中默认情况下不会扩展document.body,因此在您将其通过选择器一次之前,它可能不会附加任何方法。请仔细阅读,这里还有其他问题。基本上-Ie不允许在9之前修改Element.prototype,因此当您通过选择器访问实际元素时,mootools会在这些元素上附加元素方法。有趣的是,我从来没有想过使用元素存储(或者更确切地说,我从来没有使用过元素存储)。我会就此回复你的…谢谢你的代码片段,迪米特尔。我似乎已经让它工作得很好了。我将更新问题以反映新的代码。我的最后一个问题是-为什么您使用
$(document.body)
而不是简单地使用
document.body
?我的印象是,
$()
试图通过读取整个页面来查找相关元素,而DOM…IE中已经定义了
document.body
。IE中默认情况下不会扩展document.body,因此在您将其通过选择器一次之前,它可能不会附加任何方法。请仔细阅读,还有其他关于他的问题