Как мне конвертировать Enter в Tab (с изменением фокуса) в IE9?Работало в IE8 - PullRequest
7 голосов
/ 18 марта 2011

У меня есть текстовый ввод с помощью обработчика события 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.) Это работает даже в браузерном режиме IE9, если я установил режим документа на «стандарты IE8». Но он не будет работать с режимом документов "стандартов IE9". (Мой DocType XHTML 1.0 Transitional.)

Поскольку это работает в IE7 и 8, может ли это быть ошибкой в ​​IE9, которая будет исправлена?

Обратите внимание: я не могу использовать input.blur() или , чтобы вручную установить новый фокус , что рекомендуется для всех других решений, которые я читал. Я уже попробовал onkeypress и onkeyup без удачи. Мне нужно универсальное решение, которое заставит веб-приложение вести себя буквально так, как если бы я нажал . Кроме того, у меня нет jQuery, однако, Dojo 1.5 доступен для меня.

Также обратите внимание: я ЗНАЮ, что это «неправильное» поведение, и что Enter должен отправить форму. Однако сотрудники моего клиента изначально пришли из среды с зеленым экраном, где Enter перемещает их между полями. Мы должны сохранить тот же интерфейс. Это то, что есть.

ОБНОВЛЕНИЕ: Я нашел разницу между IE8 и IE9. В IE8 мой параметр myEvent.keyCode сохраняется. В IE9 это не так. Я могу обновить window.event.keyCode, и он будет держаться, но это не повлияет на то, что произойдет позже. Аааа ... Есть идеи?

Ответы [ 9 ]

15 голосов
/ 31 марта 2011

Похоже, что события IE9 неизменны.После того, как они были запущены, вы не можете изменять их свойства, просто предотвратите дефолт () или отмените их.Поэтому лучше всего отменить любые события «ввода» и повторно отправить новое событие 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
    }
}

Вот документация MSDN, касающаяся событий IE9 DOM:

Объект события - 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

3 голосов
/ 05 апреля 2011

Вот другая идея;измените on submit так, чтобы он вызывал функцию вместо обработки формы.в функции проверьте все поля, чтобы убедиться, что они не заполнены, затем сфокусируйтесь на следующем поле, которое не имеет значения.
Таким образом, они вводят значение в поле 1, нажимают клавишу ввода, и функция запускается.он видит, что поле 1 заполнено, а поле 2 нет, поэтому сфокусируйтесь на поле 2.
Затем, когда все поля заполнены, отправьте форму на обработку.
Если в форме есть поля, которые могут быть пустымиВы можете использовать логический массив, который будет отслеживать, какие поля получили фокус, используя событие onfocus ().

Просто нестандартная идея.

3 голосов
/ 05 апреля 2011

В предыдущей версии IE было разрешено нестандартное свойство записи event.keyCode, теперь IE9 соответствует стандартам.

Возможно, вы захотите рассмотреть функциональность , которую вы ищете: вы хотите, чтобы клавиша ввода работала как клавиша табуляции, то есть перемещала фокус на следующее (текстовое) поле ввода. Есть больше способов сделать это. Одним из них является использование атрибута 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

[ EDIT ] отредактировал функции (см. Jsfiddles), чтобы использовать делегирование событий и заставить все это работать и в Opera. И эта версия также имитирует Shift-TAB.

2 голосов
/ 11 августа 2011

Код выше вызывает проблемы.Вот код, который поможет вам.Работает на IE9, FF5 и т.д.

1 голос
/ 12 января 2012

Используйте 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 позаботится об этом

1 голос
/ 13 ноября 2011

Код Майка Фдза превосходен. Чтобы пропустить скрытые поля, вы можете изменить строку

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];
1 голос
/ 02 июня 2011
Элемент

A <button> на странице вызовет эту проблему.

В IE9 элемент <button> получает фокус при нажатии Enter.Любая кнопка отправки или сброса также вызовет проблему.Если вы не используете submit / reset, вы можете исправить это, изменив все кнопки на <input type="button"> или установив атрибут типа кнопки для кнопки.то есть

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

В качестве альтернативы, согласно ответу KooiInc, вы можете отредактировать свой javascript, используя event.preventDefault();, чтобы не допустить такого действия клавиши Enter, и явно вызывать focus () для следующего элемента в порядке табуляции.

Вот некоторый тестовый код, который я написал, который демонстрирует проблему с элементом button (обратите внимание на синее кольцо фокусировки на button3 в IE9):

<!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>
0 голосов
/ 17 апреля 2015

Чтобы предотвратить «событие отправки», инициируемое клавишей Enter в вашей форме в IE9, удалите любую кнопку внутри области формы. Поместите его (кнопку) за пределы области формы.

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>
0 голосов
/ 02 марта 2012

Вот что я сделал с тем, что нашел в интернете:

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