【问题标题】:three button keyCode hotkey javascript三键 keyCode 热键 javascript
【发布时间】:2016-02-07 02:25:29
【问题描述】:

从另一个 stackoverflow 帖子 (How can I add a JavaScript keyboard shortcut to an existing JavaScript Function?) 我有这个热键代码:

function doc_keyPress(e) {
    if (e.shiftKey && e.keyCode == 80) {
       //do something
    }
}

document.addEventListener('keyup', doc_keyPress, false);

使用两个键。但是用三个键,比如 shift + l + m 就不行了。

if 语句是:

if (e.shiftKey && e.keyCode == 76 && e.keyCode == 77) {}

这同样不起作用。

我如何让这个工作为 shift + l + m.

【问题讨论】:

  • e.shiftKey && e.keyCode == 76 && e.keyCode == 77 - 只有当 keyCode 是两个不同的值(76 和 77)时才为真
  • 啊我明白了,那是怎么做到的?
  • 你需要检查shift + l,存储一些标志或其他东西,然后如果shift + m是下一个关键事件,做你的事情 - 否则,清除标志,这样只有正确的sequence 触发你的代码
  • e.keyCodee.charCode ? firefox 在 keyPress 上有keyCode == 0

标签: javascript


【解决方案1】:

棘手,棘手,但我设法让它工作。请注意,浏览器有自己的热键(如 chrome [ctrl]+[shift]+i),可能会覆盖该功能。

<!DOCTYPE html>
<html>
<body>
<input id="myInput" onkeydown="keyDownEvent(event)" onkeyup="resetKeys()">
</body>
</html>
<script>
var key1Pressed=false;
var key2Pressed=false;

function resetKeys(){
    key1Pressed=false;
    key2Pressed=false;
}
function keyDownEvent(e){
    e=e||event, chrCode=(typeof e.which=="number")?e.which:e.keyCode;

    if (e.shiftKey && chrCode === 76) key1Pressed=true;
    if (e.shiftKey && chrCode === 77) key2Pressed=true;

    if(key1Pressed && key2Pressed){

        alert('Three Keys Are Pressed');

        key1Pressed=false;
        key2Pressed=false;
    }
}

document.getElementById('myInput').focus();
</script>

【讨论】:

    【解决方案2】:

    使用闭包,我想你可以做这样的事情

    var doc_keypress = (function() {
        var prevWasL = false;
        return function(e) {
            if (e.type == 'keypress') {
                if (e.shiftKey && !(e.ctrlKey || e.metaKey)) {
                    if (prevWasL) {
                        if (e.charCode == 77) {
                            console.log('doing it');
                            prevWasL = false;
                            return; 
                        }
                    }
                    if (e.charCode == 76) {
                        prevWasL = true;
                        return;
                    }
                }
                prevWasL = false;
            } else { // keyup
                if (e.key == 'Shift') {
                    prevWasL = false;
                }
            }
        }
    }());
    
    document.addEventListener('keypress', doc_keypress);
    document.addEventListener('keyup', doc_keypress);
    

    同时添加 keypress 和 keyup 事件监听器,以便场景

    Shift + L,同时释放,Shift + M,不会触发误报

    这需要 shift 然后 L 然后按 M 的顺序按... >

    注意:我使用 charCode,因为至少是 firefox,keyCode 在 keyPress 事件中始终为 0

    【讨论】:

      【解决方案3】:

      如果您尝试双击或三次按键并在此之后捕获事件,我已经编写了一个简单的助手:

      function KeyPress(_opts) {
        this.opts = Object.assign({}, {
          counts: {},
          timeouts: {},
          timeBetweenPresses: 300
        }, _opts || {});
      }
      
      KeyPress.prototype.bubbledReset = function bubbledReset(keyCode) {
        var self = this;
        if (this.opts.timeouts[keyCode]) {
          clearTimeout(this.opts.timeouts[keyCode]);
          this.opts.timeouts[keyCode] = 0;
        }
        this.opts.timeouts[keyCode] = setTimeout(function () {
          self.opts.counts[keyCode] = 0;
        }, this.opts.timeBetweenPresses);
      };
      
      KeyPress.prototype.onTap = function onTap(cb) {
        var self = this;
        return function handler(event) {
          self.opts.counts[event.keyCode] = self.opts.counts[event.keyCode] || 0;
          self.opts.counts[event.keyCode]++;
          self.bubbledReset(event.keyCode);
          cb(event.keyCode, self.opts.counts[event.keyCode]);
        };
      };
      

      用法 只需使用 onTap 方法进行实例化:

      var keyPress = new KeyPress();
      
      document.addEventListener('keyup', keyPress.onTap(function (keyCode, count) {
        if (keyCode === 68 && count === 3) {
          // 68 was tapped 3 times (D key)
        }
        if (keyCode === 13 && count === 6) {
          // 13 was tapped 6 times (ENTER key)
        }
      }));
      

      希望这对其他人有帮助!

      或者如果你喜欢es6:

      class KeyPress {
        constructor(_opts) {
          this.opts = Object.assign({}, {
            counts: {},
            timeouts: {},
            timeBetweenPresses: 300
          }, _opts || {});
        }
      
        bubbledReset(keyCode) {
          if (this.timeouts[keyCode]) {
            clearTimeout(this.timeouts[keyCode]);
            this.timeouts[keyCode] = 0;
          }
          this.timeouts[keyCode] = setTimeout(() => {
            this.counts[keyCode] = 0;
          }, this.timeBetweenPresses);
        }
      
        onTap(cb) {
          return event => {
            this.counts[event.keyCode] = this.counts[event.keyCode] || 0;
            this.counts[event.keyCode]++;
            this.bubbledReset(event.keyCode);
            cb(event.keyCode, this.counts[event.keyCode]);
          };
        }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-22
        • 2011-06-12
        • 1970-01-01
        • 1970-01-01
        • 2011-08-03
        • 1970-01-01
        • 2011-08-30
        • 1970-01-01
        相关资源
        最近更新 更多