如何在 IE9 中将 Enter 转换为 Tab(焦点更改)?它在IE8中工作

Posted

技术标签:

【中文标题】如何在 IE9 中将 Enter 转换为 Tab(焦点更改)?它在IE8中工作【英文标题】:How do I convert Enter to Tab (with focus change) in IE9? It worked in IE8 【发布时间】:2011-07-17 21:34:39 【问题描述】:

我有一个带有 onkeydown 事件处理程序的文本输入,它通过将事件的 keyCode 从 13 更改为 9 来将 转换为

<input type="text" onkeydown="enterToTab(event);" onchange="changeEvent(this);" 
       name="" value="" />
<!-- Other inputs exist as created via the DOM, but they are not sibling elements. -->

javascript

function enterToTab(myEvent) 
    if (myEvent.keyCode == 13) 
        myEvent.keyCode = 9;
    

function changeEvent(myInput)  var test = "hello"; 

在 IE8 中,这会导致 onchange 事件触发,但在 IE9 中不会发生。相反,输入字段保持焦点。我怎样才能做到这一点? (它适用于 Firefox 3.6 和 Chrome 10.0。)如果我将文档模式设置为“IE8 标准”,这甚至适用于浏览器模式 IE9。但它不适用于“IE9 标准”的文档模式。 (我的 DocType 是 Xhtml 1.0 Transitional。)

既然它在 IE7 和 8 中工作,这可能是 IE9 中的一个错误,会得到修复吗?

请注意:我不能使用input.blur()手动设置新焦点,这是我读过的所有其他解决方案所建议的。我已经尝试过 onkeypress 和 onkeyup 没有运气。我需要一个通用的解决方案,它会导致 Web 应用程序的行为就像我点击了 一样。另外,我没有 jQuery,但是我可以使用 Dojo 1.5。

另请注意:我知道这是“错误”行为,Enter 应该提交表单。但是,我客户的员工最初来自绿屏环境,其中 Enter 在字段之间移动他们。我们必须保留相同的 UI。就是这样。

更新:我发现 IE8 和 IE9 之间存在差异。在 IE8 中,我的 myEvent.keyCode 设置成立。在 IE9 中,它不会。我可以更新window.event.keyCode,它会保持不变,但这不会影响以后发生的事情。啊……有什么想法吗?

【问题讨论】:

我也遇到了同样的问题,但是是通过 COM 对象。我已经把它贴在[这里][1]。有人评论了相同的 JavaScript 问题。此外,我们公司已经打开了一个微软案例,希望得到一个真正的答案。我会用任何有用的东西更新我的问题。谢谢。 [1]:***.com/questions/5127079/… 问题是您为什么要这样做。 Tab 是在字段之间导航的键。 Enter 用于提交表单。用户期望这种行为,为什么要混淆他们呢? 另外,这不是 IE 9 中的错误。键盘 Event 对象的 keyCode 属性在 IE 我们的用户经常希望回车键移动到下一个输入字段。这种行为可能来自较旧的 windows/dos 程序 IE11 正确修复了这个问题(焦点不动)。 IE10 类型的作品(输入模糊但按钮没有获得焦点)。使用output.jsbin.com/nideqoq/quiet 测试行为 【参考方案1】:

看起来 IE9 事件是不可变的。一旦它们被解雇,您就无法更改它们的属性,只需 preventDefault() 或取消它们。因此,您最好的选择是取消任何“输入”事件并从文本输入重新调度一个新的 DOM 事件。

例子

function enterToTab(event)
    if(event.keyCode == 13)
        var keyEvent = document.createEvent("Event");
        // This is a lovely method signature
        keyEvent.initKeyboardEvent("onkeydown", true, true, window, 9, event.location, "", event.repeat, event.locale);
        event.currentTarget.dispatchEvent(keyEvent);
        // you may want to prevent default here
    

这是关于 IE9 DOM 事件的 MSDN 文档:

事件对象 - http://msdn.microsoft.com/en-us/library/ms535863(v=vs.85).aspx

createEvent - http://msdn.microsoft.com/en-us/library/ff975304(v=vs.85).aspx

初始化键盘事件 - http://msdn.microsoft.com/en-us/library/ff975297(v=vs.85).aspx

【讨论】:

【参考方案2】:

以前的 IE 版本允许非标准可写event.keyCode 属性,IE9 现在符合标准。

您可能需要考虑您所追求的功能:您想让 Enter 键的行为类似于 Tab 键,即将焦点移动到下一个(文本)输入字段。还有更多方法可以做到这一点。其中之一是使用文本输入字段的tabindex 属性。如果您使用此 tabindex 属性对表单中的字段进行排序,那么我在这里介绍的函数可能会产生与您之前的 keyCode 方法相同的结果。这是我在this jsfiddle 中测试的两个函数。 (文本)输入字段现在看起来像:

<input type="text" 
       onkeypress="nextOnEnter(this,event);" 
       name="" value="" 
       tabindex="1"/>

用于制表符的函数:

function nextOnEnter(obj,e)
    e = e || event;
    // we are storing all input fields with tabindex attribute in 
    // a 'static' field of this function using the external function
    // getTabbableFields
    nextOnEnter.fields = nextOnEnter.fields || getTabbableFields();
    if (e.keyCode === 13) 
        // first, prevent default behavior for enter key (submit)
        if (e.preventDefault)
            e.preventDefault();
         else if (e.stopPropagation)    
          e.stopPropagation();
         else    
          e.returnValue = false;
        
       // determine current tabindex
       var tabi = parseInt(obj.getAttribute('tabindex'),10);
       // focus to next tabindex in line
       if ( tabi+1 < nextOnEnter.fields.length )
         nextOnEnter.fields[tabi+1].focus();
        
    


// returns an array containing all input text/submit fields with a
// tabindex attribute, in the order of the tabindex values
function getTabbableFields()
    var ret = [],
        inpts = document.getElementsByTagName('input'), 
        i = inpts.length;
    while (i--)
        var tabi = parseInt(inpts[i].getAttribute('tabindex'),10),
            txtType = inpts[i].getAttribute('type');
            // [txtType] could be used to filter out input fields that you
            // don't want to be 'tabbable'
            ret[tabi] = inpts[i];
    
    return ret;

如果您不想使用 tabindex 并且您的所有输入字段都是 'tabbable',see this jsfiddle

[EDIT] 编辑函数(参见 jsfiddles)以利用事件委托并使其在 Opera 中也能正常工作。 this version 也模仿 shift-TAB。

【讨论】:

【参考方案3】:

这是一个不同的想法;更改 on submit 以便它调用函数而不是处理表单。在函数中检查所有字段以查看它们是否为空白,然后关注下一个没有值的字段。 所以他们在字段 1 中输入一个值,按回车键,函数就会运行。它看到字段 1 已满,但字段 2 未满,因此请关注字段 2。 然后当所有字段都填满时,提交表单进行处理。 如果表单具有可以为空的字段,您可以使用布尔数组来跟踪使用 onfocus() 事件获得焦点的字段。

只是一个跳出框框的想法。

【讨论】:

【参考方案4】:

页面上的&lt;button&gt; 元素会导致此问题。

在 IE9 中,当按下 Enter 时,&lt;button&gt; 元素获得焦点。任何提交或重置按钮也会导致问题。如果您不使用提交/重置,则可以通过将所有按钮更改为 &lt;input type="button"&gt; 或将 button's type attribute 设置为按钮来解决此问题。即

<button type="button">Click me!</button>

或者根据 KooiInc 的回答,您可以编辑您的 javascript 以使用 event.preventDefault(); 来防止 Enter 键以这种方式发生作用,并在 Tab 键顺序中的下一个元素上显式调用 focus()。

这是我编写的一些测试代码,用于演示按钮元素的问题(注意 IE9 中 button3 上的蓝色焦点环):

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>IE problem with Enter key and &lt;button&gt; elements</title>
</head>

<body>
    <script>
        function press(event) 
            if (event.keyCode == 13) 
                document.getElementById('input2').focus();
                // In IE9 the focus shifts to the <button> unless we call preventDefault(). Uncomment following line for IE9 fix. Alternatively set type="button" on all button elements and anything else that is a submit or reset too!.
                // event.preventDefault && event.preventDefault();
            
        
    </script>
    <input id="input1" type="text" onkeypress="press(event)" value="input1. Press enter here." /><br />
    <input id="input2" type="text" value="input2. Press enter here." /><br />
    <input  id="button1" type="button" value='I am an <input type="button">' /><br />
    <button id="button2" type="button">I am a &lt;button type="button"&gt;</button><br />
    <button id="button3">I am a &lt;button&gt;. I get focus when enter key pressed in IE9 - wooot!</button><span>As per Microsoft docs on <a target="_tab" href="http://msdn.microsoft.com/en-us/library/ms534696%28v=vs.85%29.aspx">BUTTON.type</a> it is because type defaults to submit.</span>
</body>
</html>

【讨论】:

【参考方案5】:

上面的代码会导致问题。这是一些可以帮助您的代码。适用于 IE9、FF5 等。

function getNextElement(field) 
    var form = field.form;
    for ( var e = 0; e < form.elements.length; e++) 
        if (field == form.elements[e]) 
            break;
        
    
    return form.elements[++e % form.elements.length];


function tabOnEnter(field, evt) 
if (evt.keyCode === 13) 
        if (evt.preventDefault) 
            evt.preventDefault();
         else if (evt.stopPropagation) 
            evt.stopPropagation();
         else 
            evt.returnValue = false;
        
        getNextElement(field).focus();
        return false;
     else 
        return true;
    

然后你应该创建你的输入文本或其他任何东西

<input type="text" id="1" onkeydown="return tabOnEnter(this,event)"/>
<input type="text" id="2" onkeydown="return tabOnEnter(this,event)"/>
<input type="text" id="3" onkeydown="return tabOnEnter(this,event)"/>
<input type="text" id="4" onkeydown="return tabOnEnter(this,event)"/>

【讨论】:

【参考方案6】:

Mike Fdz 的代码非常棒。为了跳过隐藏字段,您可能需要更改行

return form.elements[++e % form.elements.length]; 

到这里:

e++;
while (form.elements[e % form.elements.length].type == "hidden") 
    e++;

return form.elements[e % form.elements.length];

【讨论】:

【参考方案7】:

使用 onpaste 和 onkeypress 之类的

假设您已经编写了一个 javascript 函数来检查文本长度,因此我们需要在按键时验证它,如下所示

<asp:TextBox ID="txtInputText" runat="server" Text="Please enter some text" onpaste="return textboxMultilineMaxNumber(this,1000);" onkeypress="return textboxMultilineMaxNumber(this,1000);"></asp:TextBox>

onkeypress 在 FF 和 IE 中都可以工作

但如果您尝试在文本框中执行 ctr+V,则 onpaste 将在 IE 中处理 FF onkeypress 处理它

【讨论】:

【参考方案8】:

这是我用我在互联网上找到的东西所做的:

function stopRKey(evt) 
 
  var evt = (evt) ? evt : ((event) ? event : null); 
  var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null); 
  if ((evt.keyCode == 13) && ((node.type=="text") || (node.type=="radio")))  
   
      getNextElement(node).focus();  
      return false;   
     
 

function getNextElement(field) 

    var form = field.form;
    for ( var e = 0; e < form.elements.length; e++) 
        if (field == form.elements[e]) 
            break;
        
    
    e++;
    while (form.elements[e % form.elements.length].type == "hidden") 
    
        e++;
    
    return form.elements[e % form.elements.length];;

【讨论】:

【参考方案9】:

为防止在 IE9 中的表单中由 Enter-Keyboard 触发“提交事件”,请取消表单区域内的任何按钮。将他(按钮)放在表单区域之外。

function enterAsTab() 
  var keyPressed = event.keyCode; // get the Key that is pressed
  if (keyPressed == 13)
   
    //case the KeyPressed is the [Enter]
    var inputs = $('input'); // storage a array of Inputs
    var a = inputs.index(document.activeElement); 
    //get the Index of Active Element Input inside the Inputs(array)
    
    if (inputs[a + 1] !== null)
    
      // case the next index of array is not null
      var nextBox = inputs[a + 1]; 
      nextBox.focus(); // Focus the next input element. Make him an Active Element
      event.preventDefault();
    
    
    return false;
   
  
  else return keyPressed;
<HTML>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body onKeyPress="return enterAsTab();">
  <input type='text' />
  <input type='text' />
  <input type='text' />
  <input type='text' />
  <input type='text' />
</body>

</HTML>

【讨论】:

为了防止在 IE9 中的表单中由 Enter-Keyboard 触发“提交事件”,请取消表单区域内的任何按钮。将他(按钮)放在表单区域之外。 最好将这些详细信息添加到答案中以使其更清晰。 好吧,吉尔莎!谢谢!

以上是关于如何在 IE9 中将 Enter 转换为 Tab(焦点更改)?它在IE8中工作的主要内容,如果未能解决你的问题,请参考以下文章

将 ENTER 键重新定义为 TAB 键

如何在sql数据库中将键盘上的“Enter”保存为<br> [重复]

在 IDEA 中将显式类型转换为 var

将 Enter 解释为带有选择的 Tab

Vim使用技巧:将Tab转换为4个空格

在 ROBOT Framework 中插入输入后如何按 TAB 或 ENTER 键