繁体   English   中英

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

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

我有一个带有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:

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应用程序表现得像我点击<Tab>一样。 另外,我没有jQuery,但Dojo 1.5可供我使用。

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

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

看起来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

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

您可能需要考虑以下功能 :您希望使输入键的行为类似于Tab键,即将焦点移动到下一个(文本)输入字段。 还有更多方法可以做到这一点。 其中一个是使用文本输入字段的tabindex属性。 如果使用此tabindex属性在表单中排序字段,则此处显示的函数可能会产生与先前keyCode方法相同的结果。 这是我在这个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', 请参阅此jsfiddle

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

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

只是一个外面的想法。

上面的代码会导致问题。 这里有一些可以帮助你的代码。 适用于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)"/>

页面上的<button>元素将导致此问题。

在IE9中,按下Enter键时, <button>元素将获得焦点。 任何提交或重置按钮也会导致问题。 如果您没有使用提交/重置,则可以通过将所有按钮更改为<input type="button">或将按钮的类型属性设置为按钮来解决此问题。

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

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

使用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将在FF中处理onkeypress处理它

要防止在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> 

这就是我通过互联网所做的事情:

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