对于模糊标题的道歉,有点难以解释......
在任何情况下,假设我有一个按钮,其中包含data-action
属性定义的操作。当用户点击所述按钮时,会发生某事,并且该按钮的操作将更改为其第二个状态。
然而,实现这一点,我发现在第一个状态被触发后,为第二个状态定义的事件会自动运行,就好像“click”持续超过函数调用并触发第二个事件一样。
一次单击应显示日志'转换为“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');
}
答案 0 :(得分:2)
好的情况:)
我看到更改事件处理程序声明的顺序解决了第一次单击的问题(并将其推迟到下一次)。
并且,我认为Mootools没有问题:你点击按钮,事件将DOM冒泡到身体,身体检查所有附加事件(委托你的情况)并且首先停止因为它找到匹配[data-action="bar"]
。并执行相关功能。身体现在继续检查其他代表团匹配(它没有理由停止!),并再次找到第二个[data-action="foo"]
匹配。
如果不使用某些标志/状态变量或延迟执行函数,我恐怕你无法避免这种情况。我认为最后一个是最好的,或者至少是最简洁的解决方案(如果适用的话,我不知道延迟是否会导致你的问题)。如果你稍稍延迟函数执行(以ms为单位),你只需跳过委托事件检查。演示 here 。
答案 1 :(得分:2)
使用您在元素上更改的第二个属性,或者更好的是,在初始事件从属性中读取它以获得性能后,更改在元素存储中保持状态的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"));
}
});