在我的淘汰应用程序中,我希望能够全局检测onkeyup / onkeydown事件并在发生这种情况时运行testMethod
。到目前为止我尝试过的是自定义绑定处理程序
ko.bindingHandlers.returnKey = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
ko.utils.registerEventHandler(element, 'keydown', function (evt) {
if (evt.keyCode === 13) {
evt.preventDefault();
evt.target.blur();
valueAccessor().call(viewModel);
}
});
}
};

但这仅适用于<input data-bind="returnKey: testMethod" />
我想要做的是对body标签或类似的数据绑定。我怎样才能做到这一点?
答案 0 :(得分:2)
您尚未指定需要支持哪些浏览器,但您可以考虑使用the event capturing phase执行此操作(支持&gt; = IE9)。这是一个跳过Knockout的版本,因为无论如何你想要全局(在正文上):
var vm = {
obs1: ko.observable("my text"),
obs2: ko.observable("my text"),
obs3: ko.observable(false)
};
function testMethod(eventArgs) {
console.log(eventArgs.keyCode);
if (eventArgs.keyCode === 13) {
eventArgs.preventDefault();
}
}
document.body.addEventListener('keydown', testMethod, true);
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<textarea data-bind="value: obs1"></textarea>
<input data-bind="value: obs2" />
<div>Test abc</div>
<input data-bind="checked: obs3" type="radio" />
<hr />
<pre data-bind="text: ko.toJSON($root)"></pre>
请注意(因为preventDefault
)现在不可能在textarea中放置一个返回(换行符),也不会在单选按钮中使用“enter”来检查它
如果需要,还可以将事件侦听器的范围附加到绑定处理程序,并使用testMethod
中的绑定observable。
答案 1 :(得分:2)
在您要捕获事件的任何区域使用事件绑定。关键事件将仅发生在可以获得焦点的元素(输入,按钮等)上,当焦点在它们上时。 (如果你也使用addEventListener
也是如此。)
<div data-bind="event:{keydown:testMethod}">
如果测试方法没有返回true,则测试方法将阻止默认行为。
testMethod: function (element, eventArgs) {
vm.pressCount(vm.pressCount() + 1);
var prevent = eventArgs.keyCode === 13;
return !prevent;
}