1

有什么想法吗?想不通...它说不arr等于[17, 67]

var key = function(keys, fn) {
    var arr = [];
    $(document).on({
        keydown: function(e) {
            arr.push(e.which);
            if (arr === keys) {
                fn();
            }
        },
        keyup: function() {
            arr = [];
        }
    });
};

// ctrl + c
key([17, 67], function() {
    alert(true);
});

这是一个小提琴

更新

由于Cymen的回答它有效,但是如果您按ctrl+a然后ctrl+ alt+a或反之亦然,您必须两次触发第二个快捷方式才能工作,有什么想法吗?

小提琴

var key = function(keys, fn) {
    var arr = [];
    $(document).on({
        keydown: function(e) {
            arr.push(e.which);
            for (var i = 0; keys[i]; i++) {
                if (arr[i] !== keys[i]) {
                    return false;
                }
            }
            fn(e);
            arr = [];
        },
        keyup: function() {
            arr = [];
        }
    });
};

// ctrl + c
key([17, 67], function() {
    alert(true);
});

// ctrl + alt + c
key([17, 18, 67], function() {
    alert('ctrl+alt+c');
});
4

1 回答 1

4

You can't use === to check if arrays are equal by content. Check it out with a JavaScript console:

[17, 35] === [17, 35]
false

a = [17, 35]
[17, 35]
a === a
true

So === on arrays is checking the reference not the value. You can use something else like underscore do the comparison or write one yourself if it is some sort of challenge. Or since you're only comparing two elements, do this:

var key = function(keys, fn) {
    var arr = [];
    $(document).on({
        keydown: function(e) {
            arr.push(e.which);
            if (arr[0] === keys[0] && arr[1] === keys[1]) {
                fn();
                arr = [];  // added this to avoid buggyness
            }
            console.log(arr);
            console.log(keys);
        },
        keyup: function() {
            arr = [];
        }
    });
};

// ctrl + c
key([17, 67], function() {
    alert(true);
});​

http://jsfiddle.net/9LbsD/

For more than two keys like CTRL+ALT+C

You need an array comparison that works for variable lengths like this one:

var equalArrays = function(array1, array2) {
    if (array1.length != array2.length) {
        return false;
    }
    for (var i=0; i < array1.length; i++) {
        if (array1[i] !== array2[i]) {
            return false;
        }
    }
    return true;    
}

var key = function(keys, fn) {
    var arr = [];
    $(document).on({
        keydown: function(e) {
            arr.push(e.which);
            console.log('arr', arr, 'keys', keys, 'match', equalArrays(arr, keys));
            if (equalArrays(arr, keys)) {
                fn();
                arr = [];                
            }
            console.log(arr);
            console.log(keys);
        },
        keyup: function() {
            arr = [];
        }
    });
};

// ctrl + c
key([17, 67], function() {
    alert(true);
});

// ctrl + alt + c
key([17, 18, 67], function() {
    alert('ctrl+alt+c');
});

http://jsfiddle.net/WZLut/

A less buggy approach

We need to keep track of which keys were pressed however a single key can only be pressed once in one combination (I'm assuming) and on keyup we should only remove the key going up not all the keys. So here is a working approach to that:

var equalArrays = function(array1, array2) {
    return _.isEqual(array1, array2);
}

var key = function(keys, fn) {
    var arr = [];
    $(document).on({
        keydown: function(e) {
            arr = _.without(arr, e.which);
            arr.push(e.which);
            if (equalArrays(arr, keys)) {
                fn();             
            }
        },
        keyup: function(e) {
            arr = _.without(arr, e.which);
            arr = _.uniq(arr);
        }
    });
};

// ctrl + c
key([17, 67], function() {
    alert('ctrl+c');
});

// ctrl + alt + c
key([17, 18, 67], function() {
    alert('ctrl+alt+c');
});

​</p>

http://jsfiddle.net/BgQUA/

于 2012-12-02T19:13:37.800 回答