停止键盘事件冒泡到父级
Posted
技术标签:
【中文标题】停止键盘事件冒泡到父级【英文标题】:Stop keyboard event bubbling to parent 【发布时间】:2021-09-05 06:45:25 【问题描述】:我们有一个包含label
和button
的药丸。选择药丸后,我们可以在Delete
或Backspace
键上将其删除。同样可以在药丸中单击按钮时删除。
问题:当我关注药丸中的button
并按下Delete
或Backspace
时,父级事件被触发(onKeyPress
函数被调用)。我面临的问题是当我们在button
上时如何阻止这些键盘事件(删除和退格)被调用。
试过了,preventDefault
和 stopPropagation
。似乎没有任何效果。
<span class="pill" tabindex="0">
<span>Pill<span>
<button type="button" class="btn">X</button>
</span>
function onKeyPress(e)
switch (e.keyCode)
case 46:
case 8:
e.preventDefault();
handleClose();
break;
default:
break;
function handleClose()
console.log('Clear the pill!');
document.querySelector('.pill')
.addEventListener('keydown', onKeyPress);
document.querySelector('.btn')
.addEventListener('click', handleClose);
【问题讨论】:
你可能只想把tabindex="-1"
放在button
上
@BCDeWitt 只会停止键盘导航到该按钮,但我仍然可以使用鼠标单击,然后按 Delete
或 Backspace
。
我认为你可以通过在父监听函数中添加if (e.target === document.querySelector('.btn') return
来解决这个问题。
【参考方案1】:
你可以像这样使用 stopPropagation。该事件从button
冒泡到其父级span
。您可以检查关键代码并相应地停止传播。
//Check for your specific keycodes here:
function clickButton(e)
if(e.keyCode == 46 || e.keyCode == 8)
e.stopPropagation();
document.querySelector('.btn')
.addEventListener('keydown', clickButton);
您可以删除检查,但即使Enter
和Tab
键也不会触发。
【讨论】:
【参考方案2】:将tabindex="-1"
添加到嵌套的<button>
元素(无论如何,您可能会想要这个),然后处理/覆盖点击产生的焦点。如果我正在构建它,如果我单击它上/内部的任何位置,我宁愿将重点放在整体药丸上,这就是我在下面的 sn-p 中演示的内容:
function onKeyPress(e)
switch (e.keyCode)
case 46:
case 8:
console.log(`$e.target.className is in focus`);
handleClose(e);
break;
default: break;
function handleClose(e)
console.log('Clear the pill!');
// Re-places focus after processing clicks on nested elements
const pillElement = document.querySelector('.pill');
pillElement.addEventListener('click', () => pillElement.focus(); );
pillElement
.addEventListener('keydown', onKeyPress);
document.querySelector('.btn')
.addEventListener('click', handleClose);
.pill
border: .25em solid black;
padding: .25em;
border-radius: 1em;
background-color: black;
color: white;
font-family: sans-serif;
.pill:focus,
.pill:active
border-color: blue;
outline: none;
.pill > .btn
border: 0;
background-color: transparent;
color: inherit;
font-family: inherit;
cursor: pointer;
border-radius: 50%;
line-height: 1.5em;
vertical-align: middle;
.pill > .btn:hover
background-color: #333;
<span class="pill" tabindex="0">
<span>Pill</span>
<button type="button" class="btn" tabindex="-1">✕</button>
</span>
【讨论】:
单击按钮时将焦点反映在药丸上并不是我要寻找的情况。我知道这可以做到,但我的情况是如何停止传播到按钮父级?以上是关于停止键盘事件冒泡到父级的主要内容,如果未能解决你的问题,请参考以下文章
Vue.js - 从孙插槽组件发射没有将 $emit 事件冒泡到父级