自动完成功能会触发任何事件吗?

80

我有一个非常简单的表单。当用户在输入字段中输入时,我想要更新页面上其他地方显示的内容。这一切都很好运行。我将更新绑定到keyupchangeclick事件。

唯一的问题是,如果您从浏览器的自动完成框中选择输入内容,则不会更新。是否有任何事件在选择自动完成时触发(显然既不是change也不是click)?请注意,如果您从自动完成框中选择并且模糊输入字段,则将触发更新。我希望它尽快触发更新。

参见:http://jsfiddle.net/pYKKp/(希望您之前填写过名为“电子邮件”的输入表单)。

HTML:

<input name="email" /> 
<div id="whatever">&lt;whatever></div> 

CSS:

div { 
    float: right; 
} 

脚本:

$("input").on('keyup change click', function () { 
   var v = $(this).val(); 
    if (v) { 
     $("#whatever").text(v);   
    }  
    else { 
        $("#whatever").text('<whatever>'); 
    } 
}); 

请查看我的答案这里 - Lev Kazakov
8个回答

82

我建议使用monitorEvents。它是由JavaScript控制台提供的函数,在web inspectorfirebug中都可以使用,它会打印出元素生成的所有事件。以下是使用示例:

monitorEvents($("input")[0]);

针对您的情况,在 Firefox 和 Opera 中,当用户从自动完成下拉菜单中选择一个项目时,都会产生一个 input 事件。在 IE7-8 中,只有在用户改变焦点后才会产生一个 change 事件。最新版本的 Chrome 也会产生类似的事件。

可以在此处找到详细的浏览器兼容性表:
https://developer.mozilla.org/en-US/docs/Web/Events/input


2
谢谢,这至少对于Firefox有帮助。change事件似乎仍然在失焦时触发,所以我不需要监听失焦事件。 - Explosion Pills
1
顺便提一下,原来监听“input”事件也有助于Opera浏览器。 - Xavi
3
我刚刚测试了input事件的监听,在我安装的所有浏览器中都可以正常工作。版本:Firefox 21.0、Opera 12.15、Chrome 27、Safari 5.1.7和IE 9。 - awe
这里有一个关于“input”事件兼容浏览器的列表。我在Chromium 55中测试过,对我来说很好用。 - MarthyM
使用monitorEvents($0)来监控当前选定的DOM元素也可能很有用,这样可以避免查找正确的选择器的麻烦。 - Guy

18

这里有一个很棒的解决方案。

$('html').bind('input', function() {
    alert('test');
});

我已在Chrome和Firefox上测试过,其他浏览器也可以使用。

我尝试了许多事件和元素,但只有在选择自动完成时才会触发这个事件。

希望这能节省一些人的时间。


这在所有浏览器中都不起作用,但是在大多数不触发“change”事件的浏览器中可以使用,所以您只需要添加一个“change”和“input”事件监听器。 $field.on('change input', changeFunction) - MarthyM
2
我使用 $input.on('keyup input change paste', callback)。效果非常好。 - Sorin C

3

正如Xavi所解释的那样,对于这个问题没有一种完全跨浏览器的解决方案,因此我自己想出了一个诀窍(需要5个步骤):
1. 我需要几个新数组:

window.timeouts     = new Array();
window.memo_values  = new Array();


2. 在输入框文本上设置焦点(如你的情况下为"email", 在我的例子中为"name"),我设置了一个间隔,例如使用jQuery(尽管不是必需品):

jQuery('#name').focus(function ()
{
    var id = jQuery(this).attr('id');
    window.timeouts[id] = setInterval('onChangeValue.call(document.getElementById("'+ id +'"), doSomething)', 500);
});


3. 当失焦时我会移除间隔计时器(不一定需要使用jQuery),并且验证值是否发生了变化。

jQuery('#name').blur(function ()
{
    var id = jQuery(this).attr('id');
    onChangeValue.call(document.getElementById(id), doSomething);
    clearInterval(window.timeouts[id]);
    delete window.timeouts[id];
});


4. 现在,检查变更的主要函数如下:

function onChangeValue(callback)
{
    if (window.memo_values[this.id] != this.value)
    {
        window.memo_values[this.id] = this.value;

        if (callback instanceof Function)
        {
            callback.call(this);
        }
        else
        {
            eval( callback );
        }
    }
}

重要提示:您可以在上述函数中使用“this”,指的是您触发的输入HTML元素。必须指定ID才能使该函数工作,并且您可以将函数、函数名称或命令字符串作为回调传递。


5. 最后,当输入值更改时,甚至从自动完成下拉列表中选择值时,您可以执行某些操作。

function doSomething()
{
    alert('got you! '+this.value);
}

重要提示:在上述函数中,您再次使用“this”指的是您触发的输入HTML元素。

可工作的FIDDLE!
我知道听起来很复杂,但实际上并不是这样。 我为您准备了一个可工作的 FIDDLE,要更改的输入名称为“name”,因此如果您曾经在在线表单中输入过您的姓名,则可能会在浏览器的自动完成下拉列表中测试。


3

添加"模糊"效果。在所有浏览器中都能工作!

$("input").on('blur keyup change click', function () {

7
当您自动完成输入时,这两个事件都不会被触发。请参阅原帖内容。 - machineaddict
@machineaddict 自动完成不是JavaScript事件。你可以编辑自动完成函数,在自动完成时运行另一个函数。如果你想分享你的自动完成函数,我可以看一下并帮助你解决问题。 - Kareem
自动完成具有一个事件,阅读此。 答案在此页面,且完美运行。 您应该编辑您的答案。 - machineaddict
第一个答案明确表示它不能在所有浏览器中工作。第二个答案做了我在之前评论中建议的事情。没有像onAutocomplete这样的事件监听器。我很高兴你找到了解决方案。感谢分享链接。它们可能会帮助别人。 - Kareem

2

使用jQuery或JavaScript检测表单输入的自动完成

方法:使用事件 input。用于选择(input或textarea)值建议。

例如,对于jQuery:

$(input).on('input', function() { 
alert("Number selected ");

});

JAVASCRIPT的例子:

<input type="text"  onInput="affiche(document.getElementById('something').text)" name="Somthing" />

这是一个开始ajax查询的例子...


1

我通过使用monitorEvents发现,至少在Chrome浏览器中,keyup事件在自动完成input事件之前被触发。在正常键盘输入时,顺序是keydown input keyup,所以在input事件之后。

我的做法如下:

let myFun = ()=>{ ..do Something };

input.addEventListener('change', myFun );

//fallback in case change is not fired on autocomplete
let _k = null;
input.addEventListener( 'keydown', (e)=>_k=e.type );
input.addEventListener( 'keyup', (e)=>_k=e.type );
input.addEventListener( 'input', (e)=>{ if(_k === 'keyup') myFun();})

需要与其他浏览器进行检查,但这可能是一种不需要间隔的方法。

1

唯一确定的方法是使用间隔。

Luca的答案对我来说太复杂了,所以我创建了自己的简短版本,希望能帮助某个人(甚至是未来的我):

    $input.on( 'focus', function(){
        var intervalDuration = 1000, // ms
            interval = setInterval( function(){

                // do your tests here
                // ..................

                // when element loses focus, we stop checking:
                if( ! $input.is( ':focus' ) ) clearInterval( interval );  

            }, intervalDuration );
    } );

在Chrome、Mozilla甚至IE上测试通过。


0

我认为你不需要为此创建一个事件:这只会发生一次,而且没有很好的浏览器支持,正如 @xavi 的答案所示。

只需在加载主体后添加一个函数,检查字段是否有任何更改默认值的情况,或者如果只是将某个值复制到另一个位置,只需复制它以确保正确初始化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接