Why is my onchange function called twice when using .focus()?

前端 未结 6 2057
执念已碎
执念已碎 2021-01-20 09:32

TLDR

  • Check this example in chrome.
  • Type someting and press tab. see one new box appear
  • type something and pr
相关标签:
6条回答
  • 2021-01-20 09:56

    There's a way easier and more reasonable solution. As you expect onchange fire when the input value changes, you can simply explicitly check, if it was actually changed.

    function onChangeHandler(e){
      if(this.value==this.oldvalue)return; //not changed really
      this.oldvalue=this.value;
      // .... your stuff
    }
    
    0 讨论(0)
  • 2021-01-20 09:59

    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>
    
    0 讨论(0)
  • 2021-01-20 10:01

    The problem is indeed that because of the focus(), the onchange is called again. I don't know if this is a good sollution, but this adding this to the function is a quick sollution:

    context.onchange = "";
    

    (The onchange is called again, but is now empty. This is also good because this function should never be called twice. There will be some interface changes in the final product that help with problems that would arise from this (mistakes and all), but in the end this is something I probably would have done anyway).

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

    As @johnhunter says, the focus does not work in the example, but it does in my complete code. I haven't looked into what's going on there, but that seems to be a separate problem.

    0 讨论(0)
  • 2021-01-20 10:10

    maybe this some help to anybody, for any reason, in chrome when you attach an event onchage to a input text, when you press the enterkey, the function in the event, do it twice, i solve this problem chaged the event for onkeypress and evaluate the codes, if i have an enter then do the function, cause i only wait for an enterkey user's, that not works for tab key.

        input_txt.onkeypress=function(evt){ 
                evt = evt || window.event;
                var charCode = evt.which || evt.keyCode;
                if(charCode === 13)  evaluate( n_rows ); 
                 };
    
    0 讨论(0)
  • 2021-01-20 10:15

    I can confirm myOnChange gets called twice on Chrome. But the context argument is the initial input field on both calls.

    If you remove the alert call it only fires once. If you are using the alert for testing only then try using console instead (although you need to remove it for testing in IE).

    EDIT: It seems that the change event fires twice on the enter key. The following adds a condition to check for the existence of the new field.

    function myOnChange(context, curNum) {
          nextNum = curNum+1;
    
          if ($('#prefix_'+nextNum).length) return false;// added to avoid duplication
    
          $(context.parentNode).append('<input type="text" onchange="return myOnChange(this,'+nextNum+')" id="prefix_'+nextNum+'" >');
          $('#prefix_'+nextNum)[0].focus();
          return false;
    }
    

    Update:

    The $('#prefix_'+nextNum).focus(); does not get called because focus is a method of the dom object, not jQuery. Fixed it with $('#prefix_'+nextNum)[0].focus();.

    0 讨论(0)
  • 2021-01-20 10:22

    Try this example:

    var curNum = 1;
    function myOnChange( context )
    {
        curNum++;
    
        $('<input type="text" onchange="return myOnChange( this )" id="prefix_'+ curNum +'" >').insertAfter( context );
        $('#prefix_'+ curNum ).focus();
    
        return false;
    }
    

    jsFiddle.

    0 讨论(0)
提交回复
热议问题