2009-10-30 2 views
11

У меня есть текстовые поля на странице, и я хочу щелкнуть ссылку, когда пользователь нажимает кнопку ввода в любом из них.Ловушка введите ключ, но не при выборе предложения автозаполнения браузера

я могу легко улавливают кнопку ввода с помощью JavaScript (путем поиска 13 в event.keyCode и event.which), но я ударил вопрос, когда функция автозаполнения пинки браузера в и предлагает то, что пользователь может понадобиться ввести. Мы находим, что пользователи часто нажимают кнопку ввода, чтобы принять предложение браузера, а не вкладку. Это смущает пользователей при немедленном нажатии ссылки, тогда как они по-прежнему предназначены для ввода текста в некоторые другие поля.

Я знаю, что было бы лучше использовать форму и кнопку отправки здесь, но по разным причинам это непрактично.

Я использую jQuery, поэтому не стесняйтесь предлагать решения jQuery.

ответ

5

Пользователю всегда нужно нажать клавишу «вниз», если они сами выбирают один из автоматически заполняемого текста, почему бы не установить переменную на что-то, когда они нажимают клавишу «вниз», а затем, если они вводят после этого, переменная. Вы не должны выполнять функцию щелчка ссылки, если переменная установлена, в противном случае это делается как обычно.

+0

Вау - это довольно Хит Робинсон, но мне это нравится! Думаю, мне придется отслеживать другие нажатия клавиш (вверх/вниз/вверх страницы вверх/вниз страницы, когда они перемещаются по списку, что-то еще, чтобы вернуться к набору текста) и установить/сбросить флаг соответствующим образом. Я чувствую расширение jQuery ... – teedyay

+0

дайте мне знать, когда плагин выходит, пожалуйста, это звучит как целая цепочка слежения за нажатием клавиши: D, gud luck – tuanvt

+0

Это хорошая идея. Помните, что пользователь может нажать клавишу «вверх» между нажатием клавиш «вниз» и «ввести». – Premasagar

3

Попробуйте установить автозаполнение в свой флажок, хотя это не является стандартным для всех браузеров, но оно работает с обычными браузерами.

<input type="text" autocomplete="off" /> 
+1

Было бы стыдно полностью потерять функцию автозаполнения. – teedyay

0

Я не уверен, что вы нажали нажатия клавиш на окне или на определенных элементах DOM. Вы должны сделать последнее (например, на элементе form), затем в обработчике событий загляните в объект события, чтобы определить, какой элемент DOM был источником события. Если это текстовое поле с автозаполнением, то return false;.

Посмотрите на обработчик события jQuery's .keypress() и свойство объекта event.target объекта события.

+0

Обнаружив ввод текста, который имел фокус, когда пользователь нажал кнопку ввода, как мне определить, была ли в то время использована автозаполнение браузера? – teedyay

+0

Я предполагаю, что вы не можете рассматривать любые текстовые поля, релевантные для автозаполнения, как имеющие отношение к отправке формы? Если нет, то вы можете совместить этот подход с предложением @ tuanvt о захвате порядка нажатия клавиш, чтобы определить, когда была нажата стрелка «вниз» (потенциально сопровождаемая стрелкой вверх). – Premasagar

+0

В любом случае, нацеливание формы, а не окна, было бы хорошей идеей, поскольку это уменьшает вероятность конфликтов в более позднем развитии. – Premasagar

9

Используя идею tuanvt в принятом ответе, я написал плагин jQuery, который выполняет эту работу.

Я отслеживаю, когда пользователь нажимает клавиши «вверх», «вниз», «вверх» и «вниз», чтобы указать, когда они находятся в поле автозаполнения. Все остальные ключи подразумевают, что они оставили его.

Я гарантирую, что мы применяем эти правила только к текстовым полям: все остальные элементы ввода ведут себя нормально.

Опера уже делает довольно хорошую работу по достижению того, чего я пытаюсь достичь, поэтому я не применяю свои правила в этом браузере - иначе пользователю нужно будет дважды нажать клавишу ввода.

Протестировано в IE6, IE7, IE8, Firefox 3.5.5, Google Chrome 3.0, Safari 4.0.4, Opera 10.00.

Он доступен на jquery.com как SafeEnter plugin. Для вашего удобства, код для версии 1.0 выглядит следующим образом:

// jQuery plugin: SafeEnter 1.0 
// http://plugins.jquery.com/project/SafeEnter 
// by teedyay 
// 
// Fires an event when the user presses Enter, but not whilst they're in the browser's autocomplete suggestions 

//codesnippet:2e23681e-c3a9-46ce-be93-48cc3aba2c73 
(function($) 
{ 
    $.fn.listenForEnter = function() 
    { 
     return this.each(function() 
     { 
      $(this).focus(function() 
      { 
       $(this).data('safeEnter_InAutocomplete', false); 
      }); 
      $(this).keypress(function(e) 
      { 
       var key = (e.keyCode ? e.keyCode : e.which); 
       switch (key) 
       { 
        case 13: 
         // Fire the event if: 
         // - we're not currently in the browser's Autocomplete, or 
         // - this isn't a textbox, or 
         // - this is Opera (which provides its own protection) 
         if (!$(this).data('safeEnter_InAutocomplete') || !$(this).is('input[type=text]') || $.browser.opera) 
         { 
          $(this).trigger('pressedEnter', e); 
         } 
         $(this).data('safeEnter_InAutocomplete', false); 
         break; 

        case 40: 
        case 38: 
        case 34: 
        case 33: 
         // down=40,up=38,pgdn=34,pgup=33 
         $(this).data('safeEnter_InAutocomplete', true); 
         break; 

        default: 
         $(this).data('safeEnter_InAutocomplete', false); 
         break; 
       } 
      }); 
     }); 
    }; 

    $.fn.clickOnEnter = function(target) 
    { 
     return this.each(function() 
     { 
      $(this) 
       .listenForEnter() 
       .bind('pressedEnter', function() 
       { 
        $(target).click(); 
       }); 
     }); 
    }; 
})(jQuery); 
+0

Вы больше не можете получить этот плагин из jquery из-за изменения нового сайта плагина, но я заметил, что вы положили на него V1.0.1 (хотя мы можем получить к нему доступ), каковы были изменения для этого и вы могли его опубликовать? :) Спасибо – GazB

+0

Для тех, кто пытается заставить эту работу работать с новейшей версией jQuery (1.9+, я думаю, это так), что .browser как ушел, но я не вижу никакого автозаполнения для Opera, так что просто удалите последнюю проверку из этой строки : if (! $ (This) .data ('safeEnter_InAutocomplete') ||! $ (This) .is ('input [type = text]') || $ .browser.opera), поэтому он читает: if (! $ (this) .data ('safeEnter_InAutocomplete') ||! $ (this) .is ('input [type = text]')) – GazB

2

выследить клавишу ввода на KeyUp случае, выбор будет завершен к тому времени, когда Вы обнаружили ввести ключ на KeyUp события.

обнаружение ввода ключа при нажатии клавиши и выполнение операции мешают функциональности автозаполнения.

1

Если вы используете новые типы форм html5 поля, вы можете изменить код teedyay, как показано ниже:

case 13: 
        // Fire the event if: 
        // - we're not currently in the browser's Autocomplete, or 
        // - this isn't a textbox, or 
        // - this is Opera (which provides its own protection) 
        if (!$(this).data('safeEnter_InAutocomplete') || !$(this).is('input([type=text],[type=email],[type=number],[type=search],[type=tel],[type=url])') || $.browser.opera) 
        { 
         ... 

Обратите внимание на новые типы входных данных.

2

JQuery - это хорошо и все, но почему бы не использовать простой JavaScript?

function submit_on_enter(e) { 
    var keycode; 
    if (window.event) keycode = window.event.keyCode; 
    else if (e) keycode = (e.keyCode ? e.keyCode : e.which); 
    else return true; 

    if (keycode == 13) { 
     if (window.previousKeyCode) { 
      // down=40,up=38,pgdn=34,pgup=33 
      if (window.previousKeyCode == 33 || window.previousKeyCode == 34 || 
       window.previousKeyCode == 39 || window.previousKeyCode == 40) { 
        window.previousKeyCode = keycode; 
        return true; 
      } 
     } 
     submit_form(); 
     return false; 
    } else { 
     window.previousKeyCode = keycode; 
     return true; 
    } 
} 
2

Это работает для меня:

$('input').keypress(function(e) { 
    if(e.which == 13) { 
     if(this.value) 
     { 
      $("#submitbutton").click(); 
     } 
    } 
}); 
+0

Keypress работает здесь, когда keydown doesnt – Sameer

0

Я сталкивался с таким же вопросом и пока не совершенны, я использовал другой подход, который я считаю проще. При создании автозаполнения я установить текущее время для выбора события, а затем сравнить его, прежде чем принимать какие-либо действия:

$('#completer').autocomplete({ 
 
    source: ['First', 'Last'], delay: 0, minLength: 0, 
 
    select: function(ev, ui) { 
 
    $(ev.target).data('lastAutocompleteSelectTimestamp', new Date().getTime()) 
 
    } 
 
}) 
 

 
$(document).on('keydown', '#completer', function(ev){ 
 
    if (ev.which != 13) return 
 
    var lastAutocompletionTime = $(ev.currentTarget).data('lastAutocompleteSelectTimestamp') 
 
    if (!lastAutocompletionTime || (new Date().getTime() - lastAutocompletionTime) > 100) 
 
    alert('Enter pressed outside autocomplete context') 
 
})
<html> 
 
<head> 
 
    <link href="https://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css" rel="stylesheet"/> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
    <script src="https://code.jquery.com/ui/1.11.0/jquery-ui.min.js"></script> 
 
</head> 
 
<body> 
 
    <input id=completer type=text /> 
 
</body> 
 
</html>

0

Другой (безопаснее) подход заключается в использовать keyup и keydown события в обнаружение изменений значения.

Autocomplete устанавливает значение послеkeyDown событие. Когда наблюдаются оба события, следующие является гораздо более надежным, чем другие решения:

var tempValue; 
// fire when enter is 1. pressed and 2. released 
function handlerEnter(type){ 
    // save the value for comparison 
    if(type == 'keyDown'){ 
     tempValue = document.activeElement.value; 
     return null; // quit 
    } 

    // quit when the value changed in between keyDown & keyUp 
    if(type == 'keyUp' && tempValue != document.activeElement.value){ 
     return null; 
    } 

    // autocomplete wasn't used 
    doStuff(); 
} 

Вы можете проверить, если document.activeElement является входом. Не стесняйтесь использовать my evil prototype extension.

Смежные вопросы