11

我在页面上有一些文本框,当用户按下其中任何一个时,我想单击一个链接。

我可以使用 javascript 轻松捕获 enter 按钮(通过查找 13 inevent.keyCodeevent.which),但是当浏览器的自动完成功能启动并建议用户可能想要输入的内容时,我遇到了问题。我们发现用户经常按 Enter 键来接受浏览器的建议,而不是按 Tab。这让用户感到困惑,因为链接被立即点击,而他们仍然打算在其他一些字段中输入文本。

我知道在这里使用表单和提交按钮会更好,但由于各种原因,这不切实际。

我正在使用 jQuery,因此请随时提供 jQuery 解决方案。

4

10 回答 10

9

在接受的答案中使用 tuanvt 的想法,我编写了一个 jQuery 插件来完成这项工作。

我跟踪用户何时按下向上、向下、向上翻页和向下翻页键来判断他们何时在自动完成框中。所有其他键都暗示他们已经离开了它。

我确保我们只将这些规则应用于文本框:所有其他输入元素都正常运行。

Opera 已经很好地完成了我想要实现的目标,因此我不会在该浏览器中强制执行我的规则——否则用户将不得不按两次 Enter。

在 IE6、IE7、IE8、Firefox 3.5.5、Google Chrome 3.0、Safari 4.0.4、Opera 10.00 中测试。

它作为SafeEnter 插件在 jquery.com 上提供。为方便起见,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);
于 2009-11-18T12:00:37.617 回答
5

如果用户选择正确选择自动完成文本之一,则用户始终必须按下向下键,为什么在按下向下键时不将变量设置为某个值,然后如果他们按回车键,则检查变量。如果设置了变量,则不应执行链接单击功能,否则照常执行。

于 2009-10-30T11:17:46.827 回答
3

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;
    }
}
于 2012-06-02T16:59:18.137 回答
3

尝试在您的复选框上设置自动完成功能,虽然这不是所有浏览器的标准,但它适用于常见浏览器。

<input type="text" autocomplete="off" />
于 2009-10-30T10:30:27.343 回答
2

这对我有用:

$('input').keypress(function(e) {
    if(e.which == 13) {
        if(this.value)
        {
            $("#submitbutton").click();
        }
    }
});
于 2012-09-06T09:24:17.790 回答
2

在 keyup 事件上跟踪 enter 键,在您检测到 keyup 事件上的 enter 键时完成选择。

在 keydown 上检测 enter 键并执行操作会干扰自动完成功能。

于 2011-07-13T21:03:27.080 回答
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)
                    {
                        ...

请注意新的输入类型。

于 2012-04-23T19:50:27.440 回答
0

我不确定您是在窗口还是在特定的 DOM 元素上捕获按键。您应该执行后者(例如在form元素上),然后在您的事件处理程序中,查看事件对象以确定哪个 DOM 元素是事件的起源。如果这是一个带有自动完成功能的文本字段,那么return false;.

看一下 jQuery 的.keypress()事件处理程序,以及event.target事件对象的属性。

于 2009-10-30T11:07:51.103 回答
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>

于 2014-10-09T21:09:04.760 回答
0

另一种(更安全)的方法是使用keyupkeydown事件来检测值的变化。

自动完成设置事件的值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是否是输入。随意使用我的邪恶原型扩展

于 2016-07-21T02:00:14.143 回答