在backbone.js 中按键? [英] Keypress in backbone.js?

查看:23
本文介绍了在backbone.js 中按键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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?

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

I have a view that works with one item at a time. I have a mouseenter - mouseleave function 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.

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

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

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

Basically If I could figure out how to fire that keyAction method 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.

我确实理解这段代码有什么问题,它无法知道我们何时在该视图中运行 keypress,我必须添加条件或其他内容来查找活动类,因此当我执行 keypress 时它知道我在谈论什么模型,这里的描述非常模糊,但我发现有问题,我只是不知道该怎么做?

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?

我的解决方案

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.

推荐答案

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

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 focus on the element you are hovering over, then you can listen for the keypress, or better yet, listen to keydown because it behaves in a more standard way cross browser.

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

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

只有某些表单元素接受focus.您可以向元素添加 contenteditabletabindex 属性,这应该允许几乎所有元素接收焦点,但是 keydown 事件赢了不会真的被炒鱿鱼!这是浏览器特定的问题.根据我的经验, 将导致在我测试过的每个浏览器(Chrome、Firefox、IE、Safari、Android 浏览器、Silk).因此,在 jsfiddle 中,我在目标元素内添加了一个跨度,将 focus 放在其上,并向其添加了 keydown 事件侦听器.

Only certain form elements accept focus. You can add contenteditable or tabindex attributes to the element, and that should allow pretty much any element to receive focus, but then the keydown event won't actually get fired! This is a browser specific issue. In my experience, a <span> will cause keydown and keyup events 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 focus on that, and added the keydown event listener to it.

因此,如果您在视图中添加了一个空的 <span>,您的代码可能如下所示:

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

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

这篇关于在backbone.js 中按键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆