阻止或检测来自自动完成列表内部的关键事件

时间:2018-07-18 19:11:35

标签: javascript html

我有一个带有多个堆叠的<input type="text">框的表单,我检查表单的keydown事件是否有按下Enter键,如果发生这种情况,则移至下一个输入,并返回false防止提交表单。 (是的,这是一种老式的方法,但是我想支持旧版浏览器。)

form.onkeydown = checkEnter;

function checkEnter(e)
{
  e = e||window.event;
  var el, tag, typ, k = e.keyCode||e.which;
  if ((k===13)&&(el = e.target||e.srcElement)&&(((tag = el.tagName)==="SELECT")||((tag==="INPUT")&&((typ = el.type)!=="submit")&&(typ!=="reset")&&(typ!=="button"))))
  {
    // focus next form element
    // ...
    return false;
  }
}

问题是,如果我在输入中按向下箭头键并且自动完成列表打开,则可以像往常一样使用鼠标从该列表中选择一个值,但是如果我改用箭头键选择一个值,然后按单击“输入”以选择该值,我的事件阻止了此事件在Firefox 61和Edge 42中发生(但确实在Chrome 67中可以正常工作)。这使得没有鼠标就无法使用自动完成功能。

我的问题是:当焦点位于自动完成历史记录列表中而不是元素本身内部时,是否可以阻止按键事件触发?或者,我的事件可以某种方式检测到自动完成列表正在显示吗?我希望在自动完成列表中按“ Enter”键来执行其默认行为,即选择自动完成条目。

请注意,Chrome浏览器可能会避免此问题,因为<input>中的值会在您导航自动填充列表时发生变化。

请注意,更改为使用keypress事件(而不是keydown)没有区别(至少在FF 61中如此)。

1 个答案:

答案 0 :(得分:0)

事实证明,影响自动完成的是 不是

return false;

相反,这是我将重点放在下一个表单元素上的部分。这解决了我遇到的特定问题(请注意,有必要对keydown而不是keypress进行更改):

form.onkeypress = checkEnter;

function checkEnter(e)
{
  e = e||window.event;
  var el, tag, typ, nextEl, k = e.keyCode||e.which;
  if ((k===13)&&(el = e.target||e.srcElement)&&(((tag = el.tagName)==="SELECT")||((tag==="INPUT")&&((typ = el.type)!=="submit")&&(typ!=="reset")&&(typ!=="button"))))
  {
    // nextEl = form element to switch focus to next
    // ...
    if (nextEl) setTimeout(function(){nextEl.focus()},0);
    return false;
  }
}

即使用keypress将焦点更改推迟到setTimeout()事件完成之后。

所以我回答了我的 specific 问题,该问题是在这种情况下解决自动完成行为。但我仍然不知道我提出的一般问题的答案,即:

  

当焦点位于内部时,我可以阻止按键事件触发吗?   自动完成历史记录列表,而不是元素本身?   或者,我的事件可以某种方式检测到自动完成   列表显示了吗?

例如,我有另一个页面,我希望在<input>中按“ Enter”以执行特定的操作,如果只按不是以选择自动完成条目,则仅按

...因此,如果有人对更普遍的问题有解决方案,请发布它!