AngularJS ng-keydown 指令仅适用于 <input> 上下文?
Posted
技术标签:
【中文标题】AngularJS ng-keydown 指令仅适用于 <input> 上下文?【英文标题】:AngularJS ng-keydown directive only working for <input> context? 【发布时间】:2013-03-20 05:52:20 【问题描述】:我对 AngularJS 还是很陌生,但到目前为止我觉得它很合我的胃口。对于我当前的项目,我需要热键功能,并且很高兴看到它从 1.1.2 版本开始就受到支持。
ng-keydown 指令 (http://code.angularjs.org/1.1.3/docs/api/ng.directive:ngKeydown) 对输入类型按预期工作,但对任何其他上下文(如 div 等)都失败了。考虑到文档另有说明,这似乎很奇怪。
这里是一个最小的例子(http://jsfiddle.net/TdXWW/12/),分别是工作和不工作:
<input ng-keydown="keypress($event)">
<div ng-keydown="keypress($event)">
注意:我知道这可以用普通的 jQuery (http://www.mkyong.com/jquery/how-to-check-if-an-enter-key-is-pressed-with-jquery/) 处理,但我更喜欢了解如何在 AngularJS 中处理它。
【问题讨论】:
不是contenteditable
的div 在单击时不会触发焦点,因此没有活动元素可将keypress
绑定到。使用 jQuery 或本机脚本尝试同样的事情有同样的问题。可以将事件绑定到文档并测试该目标不是输入。不确定您的用例是什么
【参考方案1】:
charlietfl 的评论清除了一切,并将事件绑定到 $(document) 按预期工作!带走的信息:AngularJS 文档并不详尽,即需要背景知识。
【讨论】:
【参考方案2】:谢谢!总结一下,我通过将 $document 注入到我的指令中来完成这个工作,然后:
MyApp.directive('myDirective', function($document)
return
...
$document.keydown(function(e)
console.log(e)
)
【讨论】:
我需要做 $($document).keydown(... 才能让它工作。我猜 jQuery-lite 没有 keydown 功能? @Crashthatch 为 jQuery-lite 使用.on('keydown')
。【参考方案3】:
我遇到了同样的问题,并且能够按照此评论中提供的这个简单提示解决它:https://***.com/a/1718035/80264
您需要给 div 一个 tabindex 以便它可以接收焦点。
<div id="testdiv" tabindex="0"></div>
【讨论】:
非常好的信息。唯一的问题是当它获得焦点时,至少在 FireFox 中,我会在元素周围得到一个大的红色边框。 我认为这是因为firefox默认处理html表单验证的方式?看看这是否有帮助:***.com/questions/3809146/… 感谢您的链接。最后,我将 ng-keydown 和 ng-keyup 添加到 body 元素中,然后在 body 控制器中调用函数。然后这些设置一个变量,但也可以广播到其他控制器。非常适合我的需求(使用 shift 选择数据)。感谢您的回复。 世界上没有足够的赞成票。这让我疯狂了一个小时。【参考方案4】:这就是我最终得到它的方式。
将ng-app
添加到html
元素,将ng-keyup
和ng-keydown
添加到body
元素:
<html ng-app="myApp" ng-controller="MainCtrl">
.....
<body ng-keydown="keyPress($event);" ng-keyup="keyRelease($event);">
然后我的控制器中的函数处理事件调用 event.which 以获取关键代码(在我的实现中,我为 rootScope 设置了一个 var,但您也可以广播到其他控制器)
$scope.keyPress = function(eve)
if (eve.which === 16) // shift
// $rootScope.$broadcast('doShift');
$rootScope.shiftOn = true;
;
;
【讨论】:
如果您使用多个子模板并且只有一个主体,这并不令人惊讶。我更喜欢自定义指令【参考方案5】:angular.module('app').directive('executeOnEnter', function ()
return
restrict: 'A',
link: function (scope, el, attrs, $rootScope)
$('body').on('keypress', function (evt)
if (evt.keyCode === 13)
el.trigger('click', function ()
);
)
,
controller: function ($rootScope)
function removeEvent()
$("body").unbind("keypress");
$rootScope.$on('$stateChangeStart', removeEvent);
)
【讨论】:
您正在绑定正文上的按键。因此,如果您的视图发生更改或您不需要绑定到其他视图时,绑定会继续 word 事件。 如果您对此感到担忧,我编辑了答案。当然,这可能会删除你之前附加到身体的东西(在按键上),所以你可能需要注意这一点。【参考方案6】:它对我来说很好,只需添加 tabindex 属性。确保 ng-keydown 包含正确的 angularjs 表达式
<div ng-keydown="keypress($event)" tabindex="0">
$scope.keypress = function(ev)
console.log('keyprez', ev);
【讨论】:
以上是关于AngularJS ng-keydown 指令仅适用于 <input> 上下文?的主要内容,如果未能解决你的问题,请参考以下文章