【问题标题】:Replace keyCode in IE 11替换 IE 11 中的 keyCode
【发布时间】:2014-10-26 17:33:12
【问题描述】:

我们使用这段代码来模拟 Tab 键和 Enter 键:

function EnterTab() {
    if (event.keyCode == 13) event.keyCode = 9;
    return false;
}

但在 IE 11 中 keyCodereadonly 并且此代码不起作用。如何解决我的代码在 IE 11 中运行的问题?

【问题讨论】:

标签: javascript jquery internet-explorer-11


【解决方案1】:

keyCode 应该在所有现代浏览器中都是只读的,仅仅是因为修改它是 hacky 和不必要的。查看您在另一个问题中提供的代码:keydown event does not fire correctly using jQuery trigger,我们可以模仿此功能,而不是尝试返回更改后的事件。

event 对象被传递给jQuery 事件处理程序时,jQuery 实际上确实允许我们修改它。由于您已标记,因此我们可以在答案中使用它,将修改传递给在同一元素上调用的trigger()

if (e.which === 13) {
    // Alter the normalised e.which property
    e.which = 9;

    // Alter the default properties for good measure
    e.charCode = 9;
    e.keyCode = 9;

    $(this).trigger(e);
    return false;
}

注意:我使用 e.which 而不是 e.keyCode,因为 jQuery 在所有浏览器中都对此进行了规范化。

这是一个演示,展示了这一点。如果您在 input 元素处于焦点时按 Enter 键,则该事件将替换为 Tab 事件:

var $input = $('input'),
    $p = $('p');

$input.on('keydown', function(e) {
    if (e.which == 13) {  
        $p.html($p.html() + 'Enter key intercepted, modifying 13 to 9.<br>');
                
        e.which = 9;
      
        e.charCode = 9;
        e.keyCode = 9;
      
        $(this).trigger(e);
      
        return false;
    }
  
    $p.html($p.html() + 'Key pressed: ' + e.keyCode + '<br>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" />
<p></p>

正如我在my answer here 中提到的,仅仅因为您正在更改事件并不意味着您的浏览器会像按下 Tab 键一样处理它。日志记录让我们知道我们的事件已被成功拦截并更改EnterTab,即使在 Internet Explorer 11 上也是如此。

【讨论】:

  • 谢谢。但是该代码不能解决我的问题。当我点击Enter 时,我希望焦点转到下一个控件。
  • @Kerezo 这就是我在您的另一个问题中回答的内容:stackoverflow.com/a/26461581/1317805。如果input 元素紧邻另一个input 元素,您可以将它与next() 结合使用,否则您将不得不寻找比当前元素高一个tabIndex 的元素。为此,请参阅此答案:stackoverflow.com/a/1803390/1317805
【解决方案2】:

我们使用这段代码来模拟 Tab 键和 Enter 键:
...
当我按 Enter 时,我希望焦点转到下一个控件。

这个想法是错误的。不要将输入更改为选项卡。通过拦截回车键来解决这个问题,将焦点设置在下一个元素上并取消事件。 jQuery解决方案:

$(function() {
  $("form").on("keypress", "input[type=text], select, textarea", function(e) {
    if (e.which === 13) {
      e.preventDefault();
      var $fields = $(this).closest("form").find(":input");
      var index = $fields.index(this);
      $fields.eq(index + 1).trigger("focus");
    }
  });
});
input,
select,
textarea {
  box-sizing: border-box;
  margin: .5em 0;
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<form method="post">
  <p>Hitting enter inside the text fields will not submit the form</p>
  <textarea rows="4"></textarea>
  <input type="text" />
  <select>
    <option>1</option>
    <option>2</option>
    <option>3</option>
  </select>
  <select>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <input type="text" />
  <input type="submit" value="sumbmit" />
</form>

jsFiddle for testing in Internet Explorer

【讨论】:

  • 它正在工作(在 Chrome、IE11、IE8 模拟中检查)。当焦点在 select 元素上并按下 enter 时,下一个控件被聚焦。
  • 如果您使用 Enter 来聚焦下一个字段,我认为拥有一个 textarea 是没有意义的。您需要抓住另一个键才能在 textarea 中换行。
  • @Rembunator:按照 OP 的要求去做。
  • @SalmanA:这很公平。但是使用 jQuery 的 :input(参见我的代码),您可以在一个选择器中找到所有表单元素。
  • 我喜欢你将 on 语句与选择器一起使用的方式。我以前没见过这个。但这不会在每个元素上都设置一个事件监听器,同时它也总是冒泡到表单元素吗?
【解决方案3】:

这在 IE9 中有效,但在 IE11 中不再有效。所以你必须找到一个能激发你想要的结果的解决方案。例如,如果你想让用户按'Enter' 转到下一个数据输入字段(就像标签一样),尝试这样的事情。

var i = 0;
var els = myform.getElementsByTagName('input').length
document.onkeydown = function(e) {
  e = e || window.event;
  if (e.keyCode == 13) {
    i++;
    i > els - 1 ? i = 0 : i = i;
    document.myform[i].focus();

  }
};
<span>Press 'enter' inside text to act like tab button</span>
<form name="myform">
  <input type="text">
  <input type="text">
  <input type="text">
</form>

jQuery 示例:

$('.info').bind('keypress', function(event) {
  if (event.which === 13) {
    var nextItem = $(this).next('.info');

    if (nextItem.size() === 0) {
      nextItem = $('.info').eq(0);
    }
    nextItem.focus();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="info" />
<input type="text" class="info" />
<input type="text" class="info" />

【讨论】:

    【解决方案4】:

    您可以在按下 Enter 键后选择下一个或上一个表单元素。

    这将捕获所有可能的表单元素。 按 shift-Enter 会将焦点移动到上一个表单元素。

    在提交按钮上按 Enter 仍将提交表单。按 shift-Enter 将聚焦前一个表单元素。

    function EnterTabTest(event) 
        {
        if (!event.shiftKey && (event.target.getAttribute('type')=='submit')) return true;
    
        event.preventDefault();
        if (event.keyCode == 13)
            {
                if (event.shiftKey)
                    $(event.target).prevAll(":input").first().focus();
                else
                    $(event.target).nextAll(':input').first().focus();
            }
        return false;
        }
    
    
    <form onkeydown='EnterTabTest(event)'>
        <input type='text' />
        <input type='text' />
        <input type='text' />
        <p>not part of the form</p>
        <select>
            <option>opt1</option>
            <option>opt2</option>
        </select>
        <p>also not part of the form</p>
        <input type='text' />
        <input type='submit' />
    
    </form>
    

    Here is a fiddle so you can try

    IE11也可以,我试过了。

    【讨论】:

    • 我添加了一些代码来防止任何提交按钮被忽略。
    • @future_readers: 仅供参考 任何带有 tabIndex 的元素(如果 tabIndex==0 也是如此)是可聚焦的(请参阅this thread。显然使用大于 0 的值(例如,如果表格在表格中)将更改下一个元素的查找方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 2017-06-16
    • 2017-05-04
    相关资源
    最近更新 更多