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

时间:2012-02-16 20:05:46

标签: events mootools

对于模糊标题的道歉,有点难以解释......

在任何情况下,假设我有一个按钮,其中包含data-action属性定义的操作。当用户点击所述按钮时,会发生某事,并且该按钮的操作将更改为其第二个状态。

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

Here is a jsFiddle

一次单击应显示日志'转换为“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');
}

2 个答案:

答案 0 :(得分:2)

好的情况:)

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

并且,我认为Mootools没有问题:你点击按钮,事件将DOM冒泡到身体,身体检查所有附加事件(委托你的情况)并且首先停止因为它找到匹配[data-action="bar"]。并执行相关功能。身体现在继续检查其他代表团匹配(它没有理由停止!),并再次找到第二个[data-action="foo"]匹配。

如果不使用某些标志/状态变量或延迟执行函数,我恐怕你无法避免这种情况。我认为最后一个是最好的,或者至少是最简洁的解决方案(如果适用的话,我不知道延迟是否会导致你的问题)。如果你稍稍延迟函数执行(以ms为单位),你只需跳过委托事件检查。演示 here

答案 1 :(得分:2)

像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"));
    }
});