为什么使用.focus()时我的onchange函数调用两次? [英] Why is my onchange function called twice when using .focus()?

查看:869
本文介绍了为什么使用.focus()时我的onchange函数调用两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TLDR




  • 检查示例在铬。

  • 键入someting,然后按标签。看到一个新的框出现

  • 键入内容,然后按输入。预计会出现两个新框。



介绍

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



应该怎么做

在输入字段中输入内容后,我想创建一个新的输入。


$ b

javascript - 需要jquery

  function myOnChange(context,curNum){
alert('onchange start');
nextNum = curNum + 1;
$(context.parentNode).append('< input type =textonchange =return myOnChange(this,'+ nextNum +')id =prefix _'+ nextNum +'>');
$('#prefix _'+ nextNum).focus();
返回false;



$ b

HTML-part

 < DIV> 
< input type =textonchange =return myOnChange(this,1); ID = prefix_1 >
< / div>

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



一个工作的例子在这里 jFiddle



onchange被调用两次: myOnChange 函数被调用,产生新的输入,调用 focus(),再次调用 myOnChange 新的输入,'内部' myOnChange 退出,然后'外部' myOnchange 退出。
$ b

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



我想停止.focus()(这似乎是问题)不要调用 onchange(),所以 myOnChange()不会被调用两次。任何人都知道如何?

解决方案

快速修复(未经测试)应该推迟到焦点)通过

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

直到事件处理程序终止。



<但是,可以使其工作没有这样的黑客;不含jQuery的示例代码:

 < head> 
< style>
input {display:block; }
< / style>
< body>
< div>< / div>
< script>
var div = document.getElementsByTagName('div')[0];

var field = document.createElement('input');
field.type ='text';
field.onchange = function(){
//只在最后一个字段的变化上添加一个新字段
if(this.num === div.getElementsByTagName('input')。length )
div.appendChild(createField(this.num + 1));

this.nextSibling.focus();
};

函数createField(num){
var clone = field.cloneNode(false);
clone.num = num;
clone.onchange = field.onchange;
return clone;
}

div.appendChild(createField(1));
< / script>


TLDR

  • Check this example in chrome.
  • Type someting and press tab. see one new box appear
  • type something and press enter. see two new boxes appear, where one is expected.

Intro
I noticed that when using enter rather then tab to change fields, my onchange function on an input field was firing twice. This page was rather large, and still in development (read: numerous other bugs), so I've made a minimal example that shows this behaviour, and in this case it even does it on 'tab'. This is only a problem in Chrome as far as I can tell.

What it should do
I want to make a new input after something is entered into the input-field. This field should get focus.

Example:

javascript - needing jquery

function myOnChange(context,curNum){
      alert('onchange start');
      nextNum = curNum+1;
      $(context.parentNode).append('<input type="text" onchange="return myOnChange(this,'+nextNum+')" id="prefix_'+nextNum+'" >');
      $('#prefix_'+nextNum).focus();
      return false;
}

HTML-part

<div>
    <input type="text" onchange="return myOnChange(this,1);" id="prefix_1">
</div>

the complete code is on pastebin. you need to add your path to jquery in the script

A working example is here on jFiddle

The onchange gets called twice: The myOnChange function is called, makes the new input, calls the focus(), the myOnChange gets called again, makes a new input, the 'inner' myOnChange exits and then the 'outer' myOnchange exits.

I'm assuming this is because the focus change fires the onchange()?. I know there is some difference in behaviour between browsers in this.

I would like to stop the .focus() (which seems to be the problem) to NOT call the onchange(), so myOnChange() doesn't get called twice. Anybody know how?

解决方案

A quick fix (untested) should be to defer the call to focus() via

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

until after the event handler has terminated.

However, it is possible to make it work without such a hack; jQuery-free example code:

<head>
<style>
input { display: block; }
</style>
<body>
<div></div>
<script>
var div = document.getElementsByTagName('div')[0];

var field = document.createElement('input');
field.type = 'text';
field.onchange = function() {
    // only add a new field on change of last field
    if(this.num === div.getElementsByTagName('input').length)
        div.appendChild(createField(this.num + 1));

    this.nextSibling.focus();
};

function createField(num) {
    var clone = field.cloneNode(false);
    clone.num = num;
    clone.onchange = field.onchange;
    return clone;
}

div.appendChild(createField(1));
</script>

这篇关于为什么使用.focus()时我的onchange函数调用两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆