【问题标题】:@keydown.ctrl and @keyup.ctrl event modifiers not responding to respective keyboard events vujs@keydown.ctrl 和 @keyup.ctrl 事件修饰符不响应各自的键盘事件 vujs
【发布时间】:2021-01-18 08:41:16
【问题描述】:

我正在编写一个 VueJS 应用程序,当用户将鼠标悬停在页面上的特定项目上时,该应用程序将显示一个自定义上下文菜单。菜单是动态的,这意味着它会随着用户悬停在不同的项目上而改变。如果用户按住控制键,菜单将是静态的,以便他们可以与菜单中的项目进行交互。

我的问题是 @keydown.ctrl="..." 事件似乎按预期响应 @keyup.ctrl="..." 事件没有。我环顾四周并尝试了不同的修饰符,例如 .exact.caputure,但它们似乎无法解决问题。

不过,有效的方法是将@keyup.ctrl 更改为@keyup.control.control 适用于 @keyup 事件,但不适用于 @keydown 事件。

@keydown@keyup 之间有什么区别需要使用不同的键修饰符?

下面是根元素的示例。

<div
  tabindex="0"
  @keydown.esc.exact="() => (displayContext = false)"
  @keydown.ctrl.exact="() => (keepContext = true)"
  @keyup.control="() => (keepContext  = false)"
>
...
</div>

【问题讨论】:

    标签: javascript html vue.js vuejs2


    【解决方案1】:

    您可以使用此网站直观地查看哪些键触发了哪些事件:https://config.qmk.fm/#/test
    甚至在这个:http://keycode.info/

    如您所见,您不能仅在 ctrl 键上设置监听器。您需要ctrl + a 或与之配对的另一个密钥才能有效地跟踪它。

    这是我们可以在不按下任何其他键的情况下跟踪ctrl 事件的最佳实现:

    • 按住 ctrl 并将鼠标悬停在 div (@mouseover.ctrl="holdCtrlAndHover")
    • 按住ctrl,离开div (@mouseleave.ctrl="holdCtrlAndLeave")
    • 按住 ctrl,将鼠标悬停在 div 上,然后单击鼠标 (@click.ctrl="hoverAndHoldCtrlThenMouseClick")

    实现示例:https://codesandbox.io/s/lingering-violet-q5gct?file=/src/App.vue


    关于MouseEvent.ctrlKey的快速参考,这里是:https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/ctrlKey

    这里是事件键监听器差异的快速解释:onKeyPress Vs. onKeyUp and onKeyDown
    很高兴知道:keypress 活动现在是deprecated

    【讨论】:

    • 在使用@mouseover.ctrl 事件进行快速测试后,按我的预期工作。感谢您的帮助!
    【解决方案2】:

    可能有几个与此相关的问题。

    当您尝试捕获输入(input、select 或 textarea)元素的 keydowns 时,捕获 keydown 事件(来自 vue 模板)是最可靠的。因为当您关注元素时,所有键盘事件都会在 this 元素上触发。在您的示例中,页面上有一些 div,这些可能不是活动元素。一个合适的解决方法是捕获 document.body 上的所有 keydown 或 key keyup 事件并检查 event.target 是否符合您的条件。另一个好处是您可以使您的模板代码更简单(尤其是当您有许多上下文菜单区域时。)

    mounted() {
       this.keepContext = false;
    
       document.body.addEventListener('keydown', event => {
          if (event.key == 'Control') { 
             this.keepContext = true;
          }
       });
       document.body.addEventListener('keyup', event => {
          if (event.key == 'Control') { 
             this.keepContext = false;
          } else if (event.key == 'Escape') { 
             // hide the contextmenu
          }
       });
    }
    

    您提出的另一个主题,@keydown.ctrl 和 @keydown.control 之间的区别。

    第一种:.ctrl 事件修饰符通常与另一个键组合使用,(例如:'@keydown.ctrl.s="autoSave"')
    第二种:.control 在你按下control 键时触发,不能与其他键组合使用。

    我已经尝试过这两种设置:

    <input
        @keydown.control="logKeydown"
        @keyup.control="logKeyup">
    >
    

    还有这个

    <input
        @keydown.ctrl="logKeydown"
        @keyup.ctrl="logKeyup">
    >
    

    使用@keydown.control 的设置确实可以可靠地工作。 @keyup.ctrl 不能可靠地工作(有时它会错过 keydown,有时它会错过 keyup)。

    总而言之,我建议在使用非输入元素时收听 document.body 上的键盘事件。其次是使用 .control 修饰符(而不是 .ctrl)修饰符。

    【讨论】:

    • 很确定.control.ctrl 的别名。不确定如何对未触发的事件做出反应,您的解决方案对我不起作用。
    • 这里是 '@keyup/keydown'.control 和 .ctrl 的演示,你可以看到它们实际上是不同的。 '@keyup.ctrl.y' 与 '@keyup.control.y' 组合的工作方式也不同,'@keyup.ctrl.y' 计数一次,而 '@keyup.control.y' 将被触发两次,这就是为什么我的结论是 .ctrl 和 .control 实际上是不同的。
    • 我宁愿有官方消息来源来确认这一点。看起来这里有一个后备。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多