无法在 Firefox 上使用键盘组合

Can't get keyboard combinations to work on Firefox

我创建了以下函数,我将其应用于各种输入以限制用户可以输入的内容。虽然此功能在 Microsoft Edge 上运行良好,但我正面临来自 Mozilla Firefox 的严重阻力,这似乎不是接受组合 shift + ←, shift + →, ctrl + A 以及单独的键例如shiftbackspacedelete

我已经修复了第二个问题,并设法让 Firefox 通过使用 isAuxiliaryKey[=46 来接受单独的密钥=] 下面显示的变量,但我找不到让它接受组合的方法。似乎 Firefox 的 keypress 功能类似于 keydown...

我真的很想解决这个问题,因为这些组合是 select 文本的一些非常常见的方式。有没有办法解决故障

代码:

/* ----- JavaScript -----  */
function restrict (el, acceptedChars, maxLength) {
  el.onkeypress = function(e) {
    var
      key = String.fromCharCode(e.which),
      isAccepted = isAuxiliaryKey || ((acceptedChars instanceof RegExp) ?
          acceptedChars.test(key) : !!~acceptedChars.indexOf(key)),
      isMaxOrLess = maxLength > el.value.length,
      isAuxiliaryKey =
          (!!~[8, 9, 13, 16, 17, 18, 35, 36, 37, 38, 39, 40, 46].indexOf(e.which)),
      hasActiveSelection = 
          el === document.activeElement && el.selectionStart !== el.selectionEnd;

    return (isAccepted && (isMaxOrLess || hasActiveSelection)) || isAuxiliaryKey;
  }
}

restrict(document.getElementById("text"), /[a-z]/, 4);
<!----- HTML ----->
<input id="text" type="text" />

从没有人回答的情况来看,我想这是一个已经并且将来可能会引起更多人关注的问题。经过反复试验,我终于想出了两个同样能很好解决这个问题的方案:

▶ 1st 选项:

处理此问题的一种方法是使用 keydown 事件而不是 keypress,因为在 keypress 上会有一些字符共享相同的 keyCode。例如,对于 keypress 事件,Deletee.which = 46。所以,如果我们允许按下 Delete,那么 也将被允许。

要解决这个问题,我们可以使用:

var a = element.onkeydown = function(e) {
    return e;
}

然后,我们可以在以下行中将e更改为a

isAuxiliaryKey = (!!~[8, 9, 13, 16, 17, 18, 35, 36, 37, 38, 39, 40, 46].indexOf(a.which))

代码:

/* ----- JavaScript -----  */
function restrict (el, acceptedChars, maxLength) {
  var a = el.onkeypress = function(e) {
   return e;
  }
  el.onkeypress = function(e) {
    var
      key = String.fromCharCode(e.which),
      isAccepted = isAuxiliaryKey || ((acceptedChars instanceof RegExp) ?
          acceptedChars.test(key) : !!~acceptedChars.indexOf(key)),
      isMaxOrLess = maxLength > el.value.length,
      isAuxiliaryKey =
          (!!~[8, 9, 13, 16, 17, 18, 35, 36, 37, 38, 39, 40, 46].indexOf(a.which)),
      hasActiveSelection = 
          el === document.activeElement && el.selectionStart !== el.selectionEnd;

    return (isAccepted && (isMaxOrLess || hasActiveSelection)) || isAuxiliaryKey;
  }
}

restrict(document.getElementById("text"), /[a-z]/, 4);
<!----- HTML ----->
<input id="text" type="text" />


▶ 2nd 选项:

除了使用keydown事件,我们还可以使用String.fromCharCode(e.which) === ""。这解决了共享相同 keyCode 的键的问题,因为即使在我们之前的示例中这两个键,Delete,产生e.which = 46,它们有以下区别:

DELETE -> String.fromCharCode(46) = ""
.      -> String.fromCharCode(46) = "."

因此,考虑到上述情况,也可以通过将 isAuxiliaryKey 变量更改为以下内容来缓解此问题:

isAuxiliaryKey =
    (!!~[8, 9, 13, 16, 17, 18, 35, 36, 37, 38, 39, 40, 46].indexOf(e.which)) && key === ""

代码:

/* ----- JavaScript -----  */
function restrict (el, acceptedChars, maxLength) {
  el.onkeypress = function(e) {
    var
      key = String.fromCharCode(e.which),
      isAccepted = isAuxiliaryKey || ((acceptedChars instanceof RegExp) ?
          acceptedChars.test(key) : !!~acceptedChars.indexOf(key)),
      isMaxOrLess = maxLength > el.value.length,
      isAuxiliaryKey =
          (!!~[8, 9, 13, 16, 17, 18, 35, 36, 37, 38, 39, 40, 46].indexOf(e.which)) && key === "",
      hasActiveSelection = 
          el === document.activeElement && el.selectionStart !== el.selectionEnd;

    return (isAccepted && (isMaxOrLess || hasActiveSelection)) || isAuxiliaryKey;
  }
}

restrict(document.getElementById("text"), /[a-z]/, 4);
<!----- HTML ----->
<input id="text" type="text" />