停止键盘事件冒泡到父级

Posted

技术标签:

【中文标题】停止键盘事件冒泡到父级【英文标题】:Stop keyboard event bubbling to parent 【发布时间】:2021-09-05 06:45:25 【问题描述】:

我们有一个包含labelbutton 的药丸。选择药丸后,我们可以在DeleteBackspace 键上将其删除。同样可以在药丸中单击按钮时删除。

问题:当我关注药丸中的button 并按下DeleteBackspace 时,父级事件被触发(onKeyPress 函数被调用)。我面临的问题是当我们在button 上时如何阻止这些键盘事件(删除和退格)被调用。

试过了,preventDefaultstopPropagation。似乎没有任何效果。

<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 只会停止键盘导航到该按钮,但我仍然可以使用鼠标单击,然后按 DeleteBackspace 我认为你可以通过在父监听函数中添加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);

您可以删除检查,但即使EnterTab 键也不会触发。

【讨论】:

【参考方案2】:

tabindex="-1" 添加到嵌套的&lt;button&gt; 元素(无论如何,您可能会想要这个),然后处理/覆盖点击产生的焦点。如果我正在构建它,如果我单击它上/内部的任何位置,我宁愿将重点放在整体药丸上,这就是我在下面的 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">&#x2715;</button>
</span>

【讨论】:

单击按钮时将焦点反映在药丸上并不是我要寻找的情况。我知道这可以做到,但我的情况是如何停止传播到按钮父级?

以上是关于停止键盘事件冒泡到父级的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js - 从孙插槽组件发射没有将 $emit 事件冒泡到父级

先看看解析,事件委托:也称事件代理 就是利用冒泡的原理 把加事件加到父级上,触发执行效果

vue--阻止冒泡、默认行为、键盘事件

vue教程1-05 事件 简写事件对象冒泡默认行为键盘事件

javascript-事件冒泡鼠标跟随键盘跟随键盘提交

阻止事件冒泡和默认行为,禁止键盘事件