<button id="btn">Click Me</button>
<ul id="menu">
<li>This is a menu.</li>
<li>This is a menu.</li>
<li>This is a menu.</li>
<li>This is a menu.</li>
</ul>
// when element is clicked it triggers the 'focus' event before the 'click' event
element.addEventListener( 'focus', ( e ) => {
e.stopImmediatePropagation(); // stops event propagation
// here goes the stuff you want to be executed once at a time
});
element.addEventListener( 'focus', ( e ) => clickFocusHandler( e, 'focus' ) );
element.addEventListener( 'click', ( e ) => clickFocusHandler( e, 'click' ) );
function clickFocusHandler( e, from ) {
console.log( 'hello from:', from );
}
如果发生focus事件,此代码将输出:
hello from focus
hello from focus
...
当它是click事件时,它将输出:
hello from focus
hello from focus
...
hello from click
hello from click
...
element.addEventListener( 'focus', ( e ) => clickFocusHandler( e ) );
element.addEventListener( 'click', ( e ) => clickFocusHandler( e ) );
function clickFocusHandler( e ) {
e.stopImmediatePropagation();
if ( e.defaultPrevented == false ) {
e.preventDefault();
// here goes the stuff you want to be executed once at a time
}
}
5条答案
按热度按时间eimct9ow1#
我认为这种行为是错误的,但从您的描述来看,这里是处理您为菜单详细描述的事件的一般思路。https://jsfiddle.net/mcso7q1y/
超文本:
jQuery:
guz6ccqo2#
你可以滚动你自己的方法来处理多个事件,使用一个小的超时来限制事件,这样只有一个事件会被触发。
x一个一个一个一个x一个一个二个x
ngynwnxp3#
创建一个名为
done
的变量,并在函数被触发时将其设置为false
,如果done
为false
,则仅“Do Something”,并在函数结束时将done
更改为true
,以便在函数再次被触发时,不会执行“Do Something”,因为“done”被设置为true
uxh89sit4#
在这里我建议一个不同的策略。与其处理全局变量和所有这些,不如跟踪菜单的状态,并在必要时进行切换。
您可能需要考虑编写一个jQuery插件来代替所有这些插件(或者使用许多现有插件中的一个)。
ivqmmu1c5#
如果你使用addEventListener()而不是
.on(event, fn)
,你可以在纯JavaScript中这样做:当一个元素被点击时,第一个被触发的事件是
focus
事件,然后传播到click
事件。使用Event.stopImmediatePropagation(),我们中断传播,这样一次只调用一个事件处理程序。您遇到的多个输出来自
event
从focus
事件 * 传播 * 到click
事件处理程序。你可以用这个来测试:
如果发生
focus
事件,此代码将输出:当它是
click
事件时,它将输出:如果在定义用于
focus
事件的侦听器之前定义click
事件侦听器,则这些输出将保持不变。event.stopImmediatePropagation()
,则在触发focus
事件时,它将抑制来自event
* 传播 * 的多个输出。但是,如果您在元素上定义了
click
事件侦听器,则在单击元素时将有双输出,因为将执行2个侦听器。**在这种情况下,**您可能希望取消该click
侦听器或使用Event.preventDefault()和Event.defaultPrevented * 属性 * 取消事件,以放弃该event
的任何多代码执行。click
事件侦听器,则在单击元素时仍会有focus
输出。所以最短的版本是在文章的顶部,如果你想用两个事件监听器和同一个处理方法,它将是这个较长的版本: