使用.focus()时,为什么我的onchange函数被调用了两次?

TLDR

  • 在chrome中检查此示例 。
  • 输入someting并按tab键。 看到一个新框出现
  • 输入内容并按enter键。 看到两个新框出现,其中一个是预期的。

介绍
我注意到当使用enter而不是tab来更改字段时,输入字段上的onchange函数会触发两次。 这个页面相当大,并且仍在开发中(阅读:许多其他错误),所以我做了一个显示这种行为的最小例子,在这种情况下它甚至在’tab’上做了。 据我所知,这只是Chrome中的一个问题。

它应该做什么
我想在输入字段输入内容后进行新输入。 这个领域应该得到关注。

例:

javascript – 需要jquery

 function myOnChange(context,curNum){ alert('onchange start'); nextNum = curNum+1; $(context.parentNode).append(''); $('#prefix_'+nextNum).focus(); return false; } 

HTML部分

 

完整的代码在pastebin上 。 你需要在脚本中添加你的jquery路径

一个工作的例子就在这里jFiddle

onchange被调用两次:调用myOnChange函数,调用新的输入,调用focus() ,再次调用myOnChange ,创建一个新输入,’ myOnChange退出,然后’外部’ myOnchange退出。

我假设这是因为焦点更改触发onchange() ? 我知道浏览器之间的行为存在一些差异。

我想停止.focus()(这似乎是问题)不要调用onchange() ,所以myOnChange()不会被调用两次。 谁知道怎么样?

快速修复(未经测试)应该是将调用推迟到focus()

 setTimeout(function() { ... }, 0); 

直到事件处理程序终止之后。

但是,它可以在没有这种黑客的情况下工作; jQuery-free示例代码:

    

有一种更简单,更合理的解决方案。 正如您期望在输入值更改时onchange fire,您可以简单地检查,如果它实际更改。

 function onChangeHandler(e){ if(this.value==this.oldvalue)return; //not changed really this.oldvalue=this.value; // .... your stuff } 

我可以确认myOnChange在Chrome上被调用了两次。 但context参数是两个调用的初始输入字段。

如果您删除警报呼叫,它只会触发一次。 如果您仅使用警报进行测试,请尝试使用控制台(尽管您需要将其删除以便在IE中进行测试)。

编辑:似乎更改事件在输入键上触发两次。 以下添加了检查新字段是否存在的条件。

 function myOnChange(context, curNum) { nextNum = curNum+1; if ($('#prefix_'+nextNum).length) return false;// added to avoid duplication $(context.parentNode).append(''); $('#prefix_'+nextNum)[0].focus(); return false; } 

更新:

$('#prefix_'+nextNum).focus(); 不会被调用因为focus是dom对象的方法,而不是jQuery。 修正了$('#prefix_'+nextNum)[0].focus();

问题确实是因为focus() ,onchange再次被调用。 我不知道这是否是一个很好的解决方案,但是这个function是一个快速的解决方案:

 context.onchange = ""; 

(onchange再次被调用,但现在是空的。这也很好,因为这个函数永远不应该被调用两次。最终产品中会有一些接口改变,有助于解决这个问题(错误和所有),但最终这是我可能会做的事情)。

sollution: http : //jsfiddle.net/k4WKH/2/

正如@johnhunter所说,焦点在示例中不起作用,但它在我的完整代码中起作用。 我没有调查那里发生了什么,但这似乎是一个单独的问题。

也许这有点帮助任何人,无论出于何种原因,当你将一个事件onchage附加到输入文本时,当你按下enterkey,事件中的函数,做两次,我解决了这个问题,为onkeypress和评估代码,如果我有一个输入然后执行该function,因为我只等待一个enterkey用户,这不适用于tab键。

  input_txt.onkeypress=function(evt){ evt = evt || window.event; var charCode = evt.which || evt.keyCode; if(charCode === 13) evaluate( n_rows ); }; 

试试这个例子:

 var curNum = 1; function myOnChange( context ) { curNum++; $('').insertAfter( context ); $('#prefix_'+ curNum ).focus(); return false; } 

jsFiddle 。