javascript 在backbone.js 中按键?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20716189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 19:05:47  来源:igfitidea点击:

Keypress in backbone.js?

javascriptjquerybackbone.js

提问by Michael Joseph Aubry

It looks like key-press can only be executed on a focus element? I don't fully buy into that, there has to be a way to execute a key-press event similar to a click event?

看起来按键只能在焦点元素上执行?我不完全相信,必须有一种方法来执行类似于点击事件的按键事件?

I have a view that works with one item at a time. I have a mouseenter- mouseleavefunction that adds a class to the item the mouse is over. When the item receives that class I want to be able to use a key-press event to run a function on that item.

我有一个视图,一次只处理一个项目。我有一个mouseenter-mouseleave函数,可以向鼠标悬停的项目添加一个类。当项目收到该类时,我希望能够使用按键事件在该项目上运行函数。

Obviously this is a slight obstacle but Id like to find out what I need to do. Below is an example view.

显然这是一个小障碍,但我想知道我需要做什么。下面是一个示例视图。

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')
        }
    }
});

So there isn't much logic here, but I am thinking I would write something like this

所以这里没有太多逻辑,但我想我会写这样的东西

    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});
        }
    }

Basically If I could figure out how to fire that keyActionmethod I should be good to go. So what are some caveats I am missing in executing some code like this? I am sure there are a few.

基本上,如果我能弄清楚如何触发该keyAction方法,我应该很高兴。那么在执行这样的代码时我缺少哪些注意事项?我确定有几个。

I do understand some of what is wrong with this code, it has no way of knowing when we run keypress in that view, I would have to add a conditional or something to find the active class, so when I execute the keypress it knows what model I am talking about, very vague description here but I get there is something wrong I am just not sure how to do this?

我确实理解这段代码的一些问题,它无法知道我们何时在该视图中运行按键,我必须添加条件或其他东西才能找到活动类,所以当我执行按键时它知道什么我正在谈论的模型,这里的描述非常模糊,但我发现有问题我只是不知道该怎么做?

My solution

我的解决方案

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});
        }
    }
}

This is cool for my app because when the user hovers over the item the user can hit a key to add data, instead of clicking.

这对我的应用程序来说很酷,因为当用户将鼠标悬停在项目上时,用户可以点击一个键来添加数据,而不是点击。

回答by RustyToms

So you are only going to be able to listen to the keypress in whichever element that you have the listener set on (or its children). And the keypress event is only going to fire if the element is focused. So I think the best solution for you would be to set focuson the element you are hovering over, then you can listen for the keypress, or better yet, listen to keydownbecause it behaves in a more standard way cross browser.

因此,您将只能在您设置了侦听器(或其子元素)的任何元素中收听按键。并且 keypress 事件只有在元素被聚焦时才会触发。所以我认为对你来说最好的解决方案是focus在你悬停的元素上设置,然后你可以听keypress,或者更好的是听,keydown因为它以更标准的方式跨浏览器运行。

Here is a working JSFiddle demonstrating this technique: http://jsfiddle.net/DfjF2/2/

这是一个演示此技术的工作 JSFiddle:http: //jsfiddle.net/DfjF2/2/

Only certain form elements accept focus. You can add contenteditableor tabindexattributes to the element, and that should allow pretty much any element to receive focus, but then the keydownevent won't actually get fired! This is a browser specific issue. In my experience, a <span>will cause keydownand keyupevents to be fired in every browser I have tested (Chrome, Firefox, IE, Safari, Android browser, Silk). So in the jsfiddle I added a span inside the target element, put focuson that, and added the keydownevent listener to it.

只有某些表单元素接受focus. 您可以向元素添加contenteditabletabindex属性,这应该允许几乎所有元素获得焦点,但keydown实际上不会触发该事件!这是浏览器特定的问题。根据我的经验,在我测试过的每个浏览器(Chrome、Firefox、IE、Safari、Android 浏览器、Silk)中都会触发a <span>will causekeydownkeyupevents。因此,在 jsfiddle 中,我在目标元素内添加了一个跨度,穿上focus它,并向其添加了keydown事件侦听器。

So if you added an empty <span>into your view, your code could look something like this:

因此,如果您<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')
        }
    }
});