Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对聚焦子体可用的单独键控事件_Javascript_Jquery_Html_Angularjs_Keydown - Fatal编程技术网

Javascript 对聚焦子体可用的单独键控事件

Javascript 对聚焦子体可用的单独键控事件,javascript,jquery,html,angularjs,keydown,Javascript,Jquery,Html,Angularjs,Keydown,我有一个(自制的)表,有几个物理行和许多逻辑行,我想用键盘滚动(也)。如果一个子体被关注并且理解了键,我希望该事件由该子体处理,并被我的表忽略 也许代码明确指出: scroll.keydown = function(e) { if (e.shiftKey | e.controlKey | e.altKey) return; var isText = e.target.type === "text"; var K = $.ui.keyCode;

我有一个(自制的)表,有几个物理行和许多逻辑行,我想用键盘滚动(也)。如果一个子体被关注并且理解了键,我希望该事件由该子体处理,并被我的表忽略

也许代码明确指出:

scroll.keydown = function(e) {
    if (e.shiftKey | e.controlKey | e.altKey) return;
    var isText = e.target.type === "text";
    var K = $.ui.keyCode;
    switch (e.keyCode) {
    case K.HOME: if (isText) return; scroll.move(-1000000); break;
    case K.END: if (isText) return; scroll.move(+1000000); break;
    case K.PAGE_UP: scroll.move(-10); break;
    case K.PAGE_DOWN: scroll.move(+10); break;
    case K.UP: scroll.move(-1); break;
    case K.DOWN: scroll.move(+1); break;
    default: return;
    }
    e.preventDefault();
};


<table tabindex="0" ng-keydown="scroll.keydown($event)" ...>
      ... <input ...>
scroll.keydown=功能(e){
如果(e.shiftKey | e.controlKey | e.altKey)返回;
var isText=e.target.type==“text”;
var K=$.ui.keyCode;
开关(如钥匙代码){
案例K.HOME:if(isText)返回;滚动移动(-1000000);中断;
案例K.END:if(isText)返回;滚动移动(+1000000);中断;
案例K.翻页:滚动。移动(-10);中断;
案例K.页面向下:滚动。移动(+10);中断;
案例K.UP:滚动移动(-1);中断;
案例K.DOWN:滚动移动(+1);中断;
默认:返回;
}
e、 预防默认值();
};
... 
它工作得很好,但它非常愚蠢:表知道它包含
input
元素,并且它知道这样的元素可以使用例如
HOME
键,因此它进行了一次测试,不使用它

那是非常错误的。现在,我添加了一个
select
,它需要在
DOWN
案例中进行类似的测试以保持其正常工作

有趣的是,还有另一个
ng keydown
——在我的表中使用组件,它处理事件的方式非常相似,但没有问题:

  • 当我按下
    向下键时,当我的内部组件被聚焦时,它首先到达事件,一切正常
  • 当我在聚焦
    选择时按下
    向下
    时,我的表格首先获取事件并滚动。我想要的是,select像往常一样打开
在Chromium版本60.0.3112.113中使用angularjs v1.5.0和1.12.1进行测试

普朗克

澄清
  • 任何对当前关注的子体没有意义的事件都应由表处理
  • 例如,
    PAGE\u UP
    对于
    输入
    来说没有任何意义,因此即使聚焦的子对象处理一些其他事件,例如,
    主页
    ,也应该滚动表格
  • 这就是为什么我添加了
    if(isText)return
    HOME
    END
    仅对
    输入有用,而对其他键无效

我已经获取了您的plunkr代码,并做了一个非常小的更改来帮助您获得您想要的

$scope.keydown函数的最顶端,我添加了一个条件,检查目标是输入还是选择,然后它将忽略滚动

这与nodeName属性一起工作,如下所示(检查$scope.keydown函数):

var-app=angular.module('plunker',[]);
应用程序控制器('MainCtrl',函数($scope){
$scope.name='World';
var数据=[];
对于(变量i=0;i<10000;++i)data.push({
id:我,
值:i*i
});
var scroll=$scope.scroll={
起点:0,
限额:10,
移动:函数(增量){
var start=scroll.start+delta;
开始=数学最大值(开始,0);
start=Math.min(start,data.length-scroll.limit);
scroll.start=开始;
},
向下键:功能(e){
//使用e.target.nodeName,您可以
//可以检查是否正在使用按键
//从输入或选择按钮触发
//然后避免表格滚动
如果(e.target.nodeName==‘输入’| | e.target.nodeName===‘选择’){
返回false;
}
如果(e.shiftKey | e.controlKey | e.altKey)返回;
var isText=e.target.type==“text”;
var K=$.ui.keyCode;
开关(如钥匙代码){
案例K.HOME:
if(isText)返回;
滚动。移动(-1000000);
打破
案例K.结束:
if(isText)返回;
滚动移动(+1000000);
打破
案例K.PAGE_UP:
滚动。移动(-10);
打破
案例K.向下翻页:
滚动。移动(+10);
打破
案例K.UP:
滚动。移动(-1);
打破
案例K.DOWN:
滚动。移动(+1);
打破
违约:
返回;
}
e、 预防默认值();
},
};
$scope.visibleData=[];
$scope.$watchCollection(“滚动”,
函数(){
对于(变量i=0;i
表格:焦点{
边框:1px纯红;
}
桌子{
边框:1px点蓝色;
}

安古拉斯普朗克
文件。写(“”);
  • 点击输入
  • 按Shift键
  • 观察上下箭头控制外部选择
  • 压力表两次
  • 请注意,箭头会滚动表格
第一 第二 第一 第二 一行 价值 {{x.id} {{x.value}}
您能否简单地捕获
元素上的keydown事件,并阻止它传播/冒泡?这将阻止其父级捕获keydown事件:)如果
选择
元素之前获取事件,则必须使用
使用捕获
,但是我不确定它是否由angular实现:(.你确定这里是这种情况吗?@Terry这意味着,我必须向所有选择添加处理程序…这不是更好。好的,我可以编写一个添加侦听器的指令…但可能已经有其他侦听器。你能创建一个简单的JSFIDLE作为示例吗?即使是一个包含select的简单表…或者,选中e.target
。如果它来自select元素,则返回false或诸如此类的值。对于不清楚我所说的内容,我深表歉意