简体   繁体   English

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

[英]How do I convert Enter to Tab (with focus change) in IE9? It worked in IE8

I have a text input with an onkeydown event handler that converts <Enter> to <Tab> by changing the event's keyCode from 13 to 9. 我有一个带有onkeydown事件处理程序的文本输入,它通过将事件的keyCode从13更改为9来将<Enter>转换为<Tab>。

<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: 使用Javascript:

function enterToTab(myEvent) {
    if (myEvent.keyCode == 13) {
        myEvent.keyCode = 9;
    }
}
function changeEvent(myInput) { var test = "hello"; }

In IE8, this caused the onchange event to fire, but that doesn't happen in IE9. 在IE8中,这导致onchange事件触发,但在IE9中不会发生这种情况。 Instead, the input field retains focus. 相反,输入字段保留焦点。 How I can I make that happen? 我怎么能做到这一点? (It works in Firefox 3.6 and Chrome 10.0.) This even works in Browser Mode IE9 if I set the Document Mode to "IE8 standards". (它适用于Firefox 3.6和Chrome 10.0。)如果我将文档模式设置为“IE8标准”,这甚至可以在浏览器模式IE9中使用。 But it won't work with a Document Mode of "IE9 standards". 但它不适用于“IE9标准”的文档模式。 (My DocType is XHTML 1.0 Transitional.) (我的DocType是XHTML 1.0 Transitional。)

Since it works in IE7 & 8, could this be a bug in IE9 that will get fixed? 由于它适用于IE7和8,这可能是IE9中的一个错误,将被修复?

Please note: I cannot use input.blur() or manually set a new focus , which is advised by all the other solutions that I've read. 请注意:我不能使用input.blur()手动设置新焦点 ,这是我读过的所有其他解决方案的建议。 I've already tried onkeypress and onkeyup with no luck. 我已经尝试过onkeypress和onkeyup而没有运气。 I need a generic solution that will cause the web app to literally behave as though I'd hit <Tab>. 我需要一个通用的解决方案,它会使Web应用程序表现得像我点击<Tab>一样。 Also, I don't have jQuery, however, Dojo 1.5 is available to me. 另外,我没有jQuery,但Dojo 1.5可供我使用。

Also note: I KNOW this is "wrong" behavior, and that Enter ought to submit the form. 还要注意:我知道这是“错误的”行为,并且输入应该提交表单。 However, my client's staff originally come from a green screen environment where Enter moves them between fields. 但是,我的客户的工作人员最初来自绿屏环境,其中Enter在字段之间移动它们。 We must retain the same UI. 我们必须保留相同的UI。 It is what it is. 就是这样。

UPDATE: I found a difference between IE8 & IE9. 更新:我发现IE8和IE9之间存在差异。 In IE8, my setting of myEvent.keyCode holds. 在IE8中,我的myEvent.keyCode设置成立。 In IE9, it does NOT. 在IE9中,它没有。 I can update window.event.keyCode , and it will hold, but that won't affect what happens later. 我可以更新window.event.keyCode ,它会保留,但这不会影响以后发生的事情。 Argh... Any ideas? 唉...有什么想法吗?

Looks like IE9 events are immutable. 看起来IE9事件是不可变的。 Once they've been fired you can't change the properties on them, just preventDefault() or cancel them. 一旦它们被解雇,你就无法改变它们的属性,只需要使用preventDefault()或取消它们。 So you best option is to cancel any "enter" events and re-dispatch a new DOM event from the text input. 因此,您最好的选择是取消任何“输入”事件并从文本输入重新分配新的DOM事件。

Example

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
    }
}

Here's the MSDN documentation around IE9 DOM events: 这是关于IE9 DOM事件的MSDN文档:

Event Object - http://msdn.microsoft.com/en-us/library/ms535863(v=vs.85).aspx 事件对象 - 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 createEvent - http://msdn.microsoft.com/en-us/library/ff975304(v=vs.85).aspx

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

The previous IE-version allowed the non standard writable event.keyCode property, IE9 now conforms to the standards. 以前的IE版本允许非标准的可写event.keyCode属性,IE9现在符合标准。

You may want to consider the functionality you are after: you want to make the enter key behave like the tab key, ie moving the focus to the next (text) input field. 您可能需要考虑以下功能 :您希望使输入键的行为类似于Tab键,即将焦点移动到下一个(文本)输入字段。 There are more ways to do that. 还有更多方法可以做到这一点。 One of them is using the tabindex attribute of the text input fields. 其中一个是使用文本输入字段的tabindex属性。 If you order the fields in your form using this tabindex attribute, the functions I present here may yield the same result as your previous keyCode method. 如果使用此tabindex属性在表单中排序字段,则此处显示的函数可能会产生与先前keyCode方法相同的结果。 Here are two functions I tested in this jsfiddle . 这是我在这个jsfiddle中测试的两个函数。 An (text) input field now looks like: (文本)输入字段现在看起来像:

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

the functions to use for tabbing: 用于制表的功能:

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;
}

If you don't want to use tabindex and all your input fields are 'tabbable', see this jsfiddle 如果您不想使用tabindex并且所有输入字段都是'tabbable', 请参阅此jsfiddle

[ EDIT ] edited functions (see jsfiddles) to make use of event delegation and make it all work in Opera too. [ 编辑 ]编辑了函数(参见jsfiddles)以利用事件委托,并使其在Opera中也能正常工作。 And this version imitates shift-TAB too. 这个版本也模仿shift-TAB。

Here is a different idea; 这是一个不同的想法; change the on submit so that it calls a function instead of processing the form. 更改提交,以便它调用函数而不是处理表单。 in the function check all the fields to see if they are blank, then focus on the next field that doesn't have a value. 在函数中检查所有字段以查看它们是否为空,然后关注下一个没有值的字段。
So they type a value into field 1, hit enter, and the function runs. 因此,他们在字段1中键入一个值,按Enter键,然后运行该函数。 it sees that field 1 is full, but field 2 isn't, so focus on field 2. 它看到字段1已满,但字段2未满,因此请关注字段2。
Then when all the fields are full, submit the form for processing. 然后,当所有字段都已满时,提交表单进行处理。
If the form has fields that can be blank, you could use a boolean array that would keep track of which fields received focus using the onfocus() event. 如果表单具有可以为空的字段,则可以使用布尔数组来跟踪使用onfocus()事件接收焦点的字段。

Just an outside the box idea. 只是一个外面的想法。

The code above causes problems. 上面的代码会导致问题。 Here's some code that will help you. 这里有一些可以帮助你的代码。 Works on IE9, FF5 etc. 适用于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;
    }
}

And then you should just create your input texts or whatever 然后你应该创建输入文本或其他任何东西

<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)"/>

A <button> element on a page will cause this problem. 页面上的<button>元素将导致此问题。

In IE9 a <button> element takes the focus when Enter is pressed. 在IE9中,按下Enter键时, <button>元素将获得焦点。 Any submit or reset button will cause the problem too. 任何提交或重置按钮也会导致问题。 If you are not using submit/reset then you can fix this by changing all buttons to <input type="button"> or by setting the button's type attribute to button. 如果您没有使用提交/重置,则可以通过将所有按钮更改为<input type="button">或将按钮的类型属性设置为按钮来解决此问题。 ie

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

Alternatively as per KooiInc's answer, you can edit your javascript to use event.preventDefault(); 或者根据KooiInc的回答,您可以编辑您的javascript以使用event.preventDefault(); to prevent the Enter key acting this way, and explicitly call focus() on the next element in the tab order. 防止Enter键以这种方式动作,并在Tab键顺序中的下一个元素上显式调用focus()。

Here is some test code I wrote that demonstrates the problem with the button element (note the blue focus ring on button3 in IE9): 下面是我编写的一些测试代码,演示了按钮元素的问题(注意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>

Mike Fdz's code is superb. Mike Fdz的代码非常棒。 In order to skip over hidden fields, you may want to change the line 为了跳过隐藏的字段,您可能想要更改该行

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

to this: 对此:

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

Use onpaste along with onkeypress like 使用onpaste和onkeypress一样

Consider you have wrriten a javascript function which checks the text lenght so we will need to validate it on key press like as below 考虑你已经编写了一个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 will work in both FF and IE onkeypress将在FF和IE中工作

but if you try to do ctr+V in textbox then onpaste will handle in IE in FF onkeypress takes care of it 但如果你尝试在文本框中执行ctr + V,那么onpaste将在FF中处理onkeypress处理它

To prevent a "submit event" triggered by Enter-Keyboard in your Form in IE9, retire any button inside the form area. 要防止在IE9中的表单中由Enter-Keyboard触发“提交事件”,请退出表单区域内的任何按钮。 Place him (button) in outside of form's area. 将他(按钮)放在表格区域的外面。

 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> 

This is what I have done with what I found over the internet : 这就是我通过互联网所做的事情:

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];;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM