js-hotkeys 绑定多个热键后多次执行解决

Jqurey版本: 1.7.1

插件: js-hotkeys0.7.9

问题描述: bind多个快捷键后, 按一个快捷键会执行多次(等于你绑定的个数)

 

这是官网的问题描述:

So there is a problem with the current codebase.Namely if you bind more than one shortcut event to a dom element then thoseevents will fire N numbers of times (where N is the number of events youassigned to an element).

 

比如:

$(document).bind('keyup', 'ctrl+t',  handle_keyboard_add_command);
$(document).bind('keyup', 'ctrl+a', handle_keyboard_add_action);
$(document).bind('keyup', {combi:'up', disableInInput: true},handle_keyboard_up);
$(document).bind('keyup', {combi:'down', disableInInput: true},handle_keyboard_down);
$(document).bind('keyup', {combi:'right', disableInInput: true},handle_keyboard_right);
$(document).bind('keyup', {combi:'left', disableInInput: true},handle_keyboard_left);
$(document).bind('keyup', {combi:'home', disableInInput: true},handle_keyboard_home);
$(document).bind('keyup', {combi:'end', disableInInput: true},handle_keyboard_end);
$(document).bind('keyup', {combi:'return', disableInInput: true},handle_keyboard_enter);
$(document).bind('keyup', {combi:'space', disableInInput: true},handle_keyboard_space);

如果你点击ctrl-t; handle_keyboard_add_command会被执行10次;

原因是源码中hotkeys.handler并没有规定事件event是从哪来的;From my analysis of the code a map of shortcuts with a key of the dom_element from which the event can be fired. If that dom_element is found, then the code looks for a match for the specific shortcut combination, if it finds a match it fires the handler. However no where in that logic does it make sure that the shortcut combination corresponds to the even fired. This isn't hard to do, we have the comibination in event.data.combi, we just have to check it. I altered the code to do this:

 

 

修改hotkeys.handler方法便可

// the event handler

    hotkeys.handler = function(event) {

        var target =hotkeys.findElement(event.currentTarget),

            jTarget = jQuery(target),

            ids = jTarget.attr('hkId');

       

        if(ids){

            ids = ids.split(';');

            var code = event.which,

                type = event.type,

                special = hotkeys.specialKeys[code],

                // prevent f5 overlapping with 't' (or f4 with 's', etc.)

                character = !special &&String.fromCharCode(code).toLowerCase(),

                shift = event.shiftKey,

                ctrl = event.ctrlKey,           

                // patch for jquery 1.2.5 && 1.2.6 see more at: 

                //http://groups.google.com/group/jquery-en/browse_thread/thread/83e10b3bb1f1c32b

                alt = event.altKey ||event.originalEvent.altKey,

                mapPoint = null;

 

            for (var x=0; x < ids.length; x++){

                if (hotkeys.triggersMap[ids[x]][type]){

                    mapPoint =hotkeys.triggersMap[ids[x]][type];

                    break;

                }

            }

           

            

            //find by: id.type.combi.options           

            if (mapPoint){

                var trigger;

                // event type is associated with the hkId

                if(!shift && !ctrl && !alt) { // No Modifiers

                    if(mapPoint[special]) {

                        trigger =mapPoint[special];

                        if(trigger &&special != event.data.combi) {

                                return;

                        }

                    } elseif(character&& mapPoint[character]) {

                        trigger =mapPoint[character];

                        if(trigger &&character != event.data.combi) {

                           return;

                        }

                    }

                } else {

                    // check combinations (alt|ctrl|shift+anything)

                    var modif = '';

                    if(alt) modif +='alt+';

                    if(ctrl) modif+= 'ctrl+';

                    if(shift) modif += 'shift+';

                    // modifiers + special keys or modifiers + character or modifiers + shiftcharacter or just shift character

                    trigger =mapPoint[modif+special];

                    // only continue if we match the combi key of the current event

                    if(trigger && (modif+special) !=event.data.combi) {

                        return;

                    }

                    if (!trigger){

                        if (character){

                            if(mapPoint[modif+character]){

                                trigger =mapPoint[modif+character];

                                if(trigger &&(modif+character) != event.data.combi) {

                                    return;

                                }

                            } elseif(mapPoint[modif+hotkeys.shiftNums[character]]){

                                trigger =mapPoint[modif+hotkeys.shiftNums[character]];

                                if(trigger &&(modif+hotkeys.shiftNums[character]) != event.data.combi) {

                                    return;

                                }

                            } elseif(modif === 'shift+' &&mapPoint[hotkeys.shiftNums[character]]) {

                                trigger = mapPoint[hotkeys.shiftNums[character]];

                                if(trigger &&hotkeys.shiftNums[character] != event.data.combi) {

                                    return;

                                }

                            }

                        }

                    }

                }

                if (trigger){

                    var result = false;

                    for (var x=0; x < trigger.length; x++){

                        if(trigger[x].disableInInput){

                            // double check event.currentTarget and event.target

                            var elem =jQuery(event.target);

                            if (jTarget.is("input") || jTarget.is("textarea") || jTarget.is("select")

                                || elem.is("input") || elem.is("textarea") || elem.is("select")) {

                                returntrue;

                            }

                        }                      

                        // call the registered callback function

                        result = result ||trigger[x].cb.apply(this, [event]);

                    }

                    return result;

                }

            }

        }

};

 

 

 

 

主要修改的是这两段代码:

if(mapPoint[special]) {

                        trigger =mapPoint[special];

                        if(trigger &&special != event.data.combi) {

                                return;

                        }

                    } elseif(character&& mapPoint[character]) {

                        trigger =mapPoint[character];

                        if(trigger &&character != event.data.combi) {

                           return;

                        }

                    }

 

 

if(mapPoint[modif+character]) {

                                trigger =mapPoint[modif+character];

                                if(trigger &&(modif+character) != event.data.combi) {

                                    return;

                                }

                            } elseif(mapPoint[modif+hotkeys.shiftNums[character]]) {

                                trigger =mapPoint[modif+hotkeys.shiftNums[character]];

                                if(trigger &&(modif+hotkeys.shiftNums[character]) != event.data.combi) {

                                    return;

                                }

                            } elseif(modif === 'shift+' &&mapPoint[hotkeys.shiftNums[character]]) {

                                trigger =mapPoint[hotkeys.shiftNums[character]];

                                if(trigger &&hotkeys.shiftNums[character] != event.data.combi) {

                                    return;

                                }

                            }

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值