keyup和keydown没有在具有敲除绑定的表上工作

时间:2014-05-07 10:54:15

标签: jquery knockout.js

我需要使用按键向上滚动表格行并按下键。为此,我需要捕获表div上的关键事件。如果我用'click'事件替换'keyup',它的工作正常但相同的代码片段不能用于按键和按键。我无法弄清楚这个问题。

$('#patientWL').on('keyup', '.bodyTable tbody tr', function(e) {
    if (e.keyCode == 38) {
        alert('key up');
    } else if (e.keyCode == 40) {
        alert('key down');
    }
});

可以看到我的问题的工作小提琴here

2 个答案:

答案 0 :(得分:1)

请注意,这不是特定问题。问题在于元素处理keyup / down / press事件的方式。

默认情况下,table(或trtd)无法获得焦点。但是,您可以通过添加tabindex属性来更改它:

<tr tabindex="0" id="example"></tr>

然后,您可以提供tr焦点,并使用hover事件模糊它:

$("#example").hover(function() {
    this.focus();
}, function() {
    this.blur();
}).keydown(function(e) {
    alert(e.keyCode);
});

tr具有焦点时,它将接受键盘事件。查看示例here.

答案 1 :(得分:0)

尽管这是一个老问题,但值得在此处添加一个自定义绑定处理程序实现(基于这些帖子:12):

ko.bindingHandlers.mapKeysToActions = {
    init: function (element, valueAccessor, allBindings, data) {
        var handler = function (data, event) {
            var keysAndActions = valueAccessor();
            if (Object.keys(keysAndActions).indexOf(event.keyCode.toString()) > -1) {
                keysAndActions[event.keyCode].call();
            };
        };
        var newValueAccessor = function () {
            return { keyup: handler };
        };
        ko.applyBindingAccessorsToNode(element, {
            event: newValueAccessor
        });
    }
};
var myModel = function () {
  var self = this;
  self.selectResult = function (item) {
    self.selectedResult(item);
  };
  self.setSelected = function ($data, $element) {
    var isSelected = self.selectedResult() == $data;
    if (isSelected) $($element).focus();
    return isSelected;
  };
  self.selectedResult = ko.observable();
  self.searchResults = ko.observableArray([
    { data1: "1", data2: "1" }, { data1: "2", data2: "2" }, { data1: "3", data2: "3" }
  ]);
  self.selectPrevious = function () {
    var index = self.searchResults().indexOf(self.selectedResult()) - 1;
    if (index < 0) index = 0;
    self.selectedResult(self.searchResults()[index]);
  };
  self.selectNext = function () {
    var index = self.searchResults().indexOf(self.selectedResult()) + 1;
    if (index >= self.searchResults().length) index = self.searchResults().length - 1;
    self.selectedResult(self.searchResults()[index]);
  };
  self.keysAndActions = {
    '38': self.selectPrevious,
    '40': self.selectNext
  };
};
ko.applyBindings(new myModel());
.btn-info {
  background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table>
  <thead>
    <tr>
	  <th>&nbsp;</th>
	  <th>table header 1</th>
	  <th>table header 2</th>
	</tr>
  </thead>
  <tbody data-bind="foreach: searchResults">
	<tr tabindex="0" 
        data-bind="click: $parent.selectResult, 
                   css: { 'btn-info': $parent.setSelected($data, $element) }, 
                   mapKeysToActions: $parent.keysAndActions">
	  <td data-bind="text: data1"></td>
	  <td data-bind="text: data2"></td>
	</tr>
  </tbody>
</table>