【问题标题】: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来解决这个问题。

标签: javascript html keyboard dom-events


【解决方案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>

    【讨论】:

    • 单击按钮时将焦点反映在药丸上并不是我要寻找的情况。我知道这可以做到,但我的情况是如何停止传播到按钮父级?
    猜你喜欢
    • 2019-09-20
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 2012-09-30
    • 2017-01-17
    • 1970-01-01
    相关资源
    最近更新 更多