看起来按键只能在焦点元素上执行?我没有完全接受这一点,必须有一种方法来执行类似于点击事件的按键事件?
我有一个视图,一次只能处理一个项目.我有一个mouseenter
- mouseleave
函数,它为鼠标结束的项添加一个类.当项目收到该类时,我希望能够使用按键事件在该项目上运行函数.
显然这是一个轻微的障碍,但我想知道我需要做什么.以下是示例视图.
var PlayerView = Backbone.View.extend({ tagName: 'div', events: { 'click .points, .assists, span.rebounds, span.steals':'addStat', 'mouseenter': 'enter', 'mouseleave': 'leave', 'keypress': 'keyAction' }, enter: function() { this.$el.addClass('hover'); }, leave: function() { this.$el.removeClass('hover'); }, keyAction: function(e) { var code = e.keyCode || e.which; if(code == 65) { alert('add assist') } } });
所以这里没有太多的逻辑,但我想我会写这样的东西
keyAction: function(e) { var code = e.keyCode || e.which; if(code == 65) { var addAssist = parseInt(this.model.get('assists')) + 1; this.model.save({assists: addAssist}); } }
基本上如果我能弄清楚如何解雇这种keyAction
方法我应该好好去.那么在执行这样的代码时我缺少哪些注意事项呢?我相信有一些.
我确实理解了这段代码的一些问题,它无法知道我们何时在该视图中运行按键,我将不得不添加条件或某些东西来查找活动类,所以当我执行按键时它知道什么我正在谈论的模型,非常模糊的描述在这里,但我得到了一些错误我不知道如何做到这一点?
我的解决方案
initialize: function() { this.listenTo(this.model, "change", this.render); _.bindAll(this, 'on_keypress'); $(document).bind('keydown', this.on_keypress); }, enter: function(e) { this.$el.addClass('hover'); }, leave: function(e) { this.$el.removeClass('hover'); }, on_keypress: function(e) { // A for assist if(e.keyCode == 65) { if(this.$el.hasClass('hover')) { var addThis = parseInt(this.model.get('assists')) + 1; this.model.save({assists: addThis}); } } // R for rebound if(e.keyCode == 82) { if(this.$el.hasClass('hover')) { var addThis = parseInt(this.model.get('rebounds')) + 1; this.model.save({rebounds: addThis}); } } // S for steal if(e.keyCode == 83) { if(this.$el.hasClass('hover')) { var addThis = parseInt(this.model.get('steals')) + 1; this.model.save({steals: addThis}); } } // 1 for one point if(e.keyCode == 49) { if(this.$el.hasClass('hover')) { var addMake = parseInt(this.model.get('made_one')) + 1; this.model.save({made_one: addMake}); var addOne = parseInt(this.model.get('points')) + 1; this.model.save({points: addOne}); } } // 2 for two points if(e.keyCode == 50) { if(this.$el.hasClass('hover')) { var addMake = parseInt(this.model.get('made_two')) + 1; this.model.save({made_two: addMake}); var addTwo = parseInt(this.model.get('points')) + 2; this.model.save({points: addTwo}); } } // 2 for two points if(e.keyCode == 51) { if(this.$el.hasClass('hover')) { var addMake = parseInt(this.model.get('made_three')) + 1; this.model.save({made_three: addMake}); var addThree = parseInt(this.model.get('points')) + 3; this.model.save({points: addThree}); } } }
这对我的应用来说很酷,因为当用户将鼠标悬停在项目上时,用户可以点击一个键来添加数据,而不是点击.
因此,您只能在监听器设置的任何元素(或其子级)上收听按键.而且,如果元素被聚焦,则按键事件才会触发.因此,我认为最适合您的解决方案是设置focus
您正在悬停的元素,然后您可以倾听keypress
,或者更好地倾听,keydown
因为它以更标准的方式跨浏览器运行.
这是一个工作的JSFiddle演示这种技术:http://jsfiddle.net/DfjF2/2/
只有某些表单元素接受focus
.你可以添加contenteditable
或tabindex
属性元素,这应该允许几乎任何元素获得焦点,但事后keydown
实际上不会被触发!这是特定于浏览器的问题.根据我的经验,我测试的每个浏览器(Chrome,Firefox,IE,Safari,Android浏览器,Silk)<span>
都会引发一个故障keydown
和keyup
事件.所以在jsfiddle中我在目标元素中添加了一个span,放在focus
那里,keydown
并向它添加了事件监听器.
因此,如果您<span>
在视图中添加了空白,则代码可能如下所示:
var PlayerView = Backbone.View.extend({ tagName: 'div', events: { 'click .points, .assists, span.rebounds, span.steals':'addStat', 'mouseenter': 'enter', 'mouseleave': 'leave', 'keydown': 'keyAction' }, enter: function() { this.$el.addClass('hover'); var span = this.$el.find('span'); span.attr('tabindex', '1').attr('contenteditable', 'true'); span.focus(); }, leave: function() { this.$el.removeClass('hover'); var span = this.$el.find('span'); span.removeAttr('contenteditable').removeAttr('tabindex'); span.blur(); }, keyAction: function(e) { var code = e.keyCode || e.which; if(code == 65) { alert('add assist') } } });