在keydown事件中处理某些键时遵从默认行为

Defer to default behavior when handling certain keys in a keydown event

本文关键字:默认 事件 keydown 处理      更新时间:2023-09-26

我使用jQuery来处理html树上的keydown事件。正如您从代码中看到的,我正在处理tab键,以便它遍历树。但是,如果它到达树的末尾,我希望它从树中抽出并进入下一个可用字段。我试过在这种情况下返回true,但那不起作用。

这会阻止其他键的功能。例如,我也想让CTRL+R工作,但当我专注于树时,它什么也不做。

我在e.stopPropagation()e.preventDefault()被调用之前返回,所以我希望我的事件能够被默认的浏览器处理程序拾取,但它们没有。我在其他帖子中读到,没有办法强制默认行为,所以我认为我最好的办法就是停止处理事件并传递它,但它并没有被传递。有人知道为什么吗?

$(treeItem).keydown(function(e) {
  return onKeyDown(obj, e);
});
var onKeyDown = function(obj, e) {
  if (!obj.isRoot) {
    switch (e.keyCode) {
      case keyCode.LEFT: collapseNode(obj); break;
      case keyCode.RIGHT: expandNode(obj); break;
      case keyCode.UP: stepUpTree(obj); break;
      case keyCode.DOWN: stepDownTree(obj); break;
      case keyCode.TAB: if (e.shiftKey) stepUpTree(obj); else stepDownTree(obj); break;
      case keyCode.ENTER: me.activateNode(obj); break;
      default: return true;
    }
  }
  e.stopPropagation();
  e.preventDefault();
}

编辑

我已经更新了代码以更准确地反映正在发生的事情。现在问题更清楚了。该事件附加到一个列表项元素,因此当我返回true时,它将继续触发所有祖先元素,直到到达根节点。此时,默认行为停止。解决方案是只有当我知道我需要时才阻止默认行为,而不是将其设置为默认行为。

你不需要返回true来告诉浏览器继续处理事件;这就是在没有preventDefaultreturn false的情况下它会做的。在您的default条款中简单地添加return。(我希望return true;是无害的,但是,嘿,你永远不知道。)

在你引用的代码中有几个bug。我假设您使用了复制粘贴(为什么要重新键入它?),所以我想知道您遇到的问题是否只是抛出错误或逻辑没有完全按照您的期望进行。

特别是

  • 您在onKeyDown函数定义的参数部分缺少obje之间的逗号,因此这是语法错误。
  • 你正在关闭e.keycode。应该是e.keyCode(注意大写的C)。如果上面缺失的逗号实际上不在您的代码中,但这是,e.keycode将始终是undefined,而不匹配您的任何情况,因此所有内容都将转到default

如果有人遇到类似的问题…

你可能想要显式地说明哪些情况应该防止默认行为,而不是将其作为默认情况。

在我的例子中,事件被绑定到一个列表项元素,这意味着如果允许传播,它将一直沿着树向上触发。没有在我的switch语句中列出的键码将只返回true并向上传播树,直到它到达根。然后,它将跳过switch语句,并调用preventDefault()

换句话说……

     var onTreeItemKeyDown = function (obj, event) {
         if (obj.id() !== me.treeDataManager.getRootItemId()) {
             switch (event.keyCode) {
                 case keyCode.LEFT: collapseNode(obj, event); break;
                 case keyCode.RIGHT: expandNode(obj, event); break;
                 case keyCode.UP: getPreviousItem(obj); haltEvent(event); break;
                 case keyCode.DOWN: getNextItem(obj); haltEvent(event); break;
                 case keyCode.ENTER: if (options.activateContent) { options.activateContent(obj); haltEvent(event); } break;
                 default: return true;
             }
         }
         return true;
     }
     var haltEvent = function (event) {
         event.stopPropagation();
         event.preventDefault();
     }
     var expandNode = function (obj, event) {
         obj.isExpanded(true);
         options.selectNode(obj);
         haltEvent(event);
     }
     var collapseNode = function (obj, event) {
         obj.isExpanded(false);
         options.selectNode(obj);
         haltEvent(event);
     }