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;

                                }

                            }

 

 

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页