Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery - Why does Trigger method call it three times?

$(document).ready(function(){
    $("input").select(function(){
        $("input").after(" Text marked!");
    });
    $("button").click(function(){
        $("input").trigger("select");
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>


<input type="text" value="Hello World"><br><br>

<button>Trigger the select event for the input field</button>

Source

Could someone tell me why select event triggered three times after a button click?

It seems that using IE and Chrome can lead different result.

like image 314
Samuel Avatar asked Nov 25 '15 02:11

Samuel


3 Answers

JQuery - Why does Trigger method call it three times?

Appear to be called twice at click event of button ; at

$("input").trigger("select");

and default handler for select event

$("input").select(function(){
    $("input").after(" Text marked!");
});

To call once at click of button , or user selection at input field , try checking event.isTrigger to determine if event called by .trigger()

$(document).ready(function(){
    $("input").select(function(e){
      if (!e.isTrigger)
        $("input").after(" Text marked!");
    });
    $("button").click(function(){
        $("input").trigger("select");
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<input />
<button>click</button>

alternatively, using setTimeout to allow selected text to be cleared before at click of button before .trigger("select") called ; original event handler should be called at most once at click of button element

$(document).ready(function() {
  
  $("input").select(function(e) {
    console.log(e);
    $("input").after(" Text marked!")
  })

  $("button").click(function() {
    setTimeout(function() {
      $("input").trigger("select");
    })
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<input />
<button>click</button>
like image 153
guest271314 Avatar answered Nov 09 '22 22:11

guest271314


Let's see, what happens here:

$(document).ready(function(){
    $("input").select(function(e){
        console.log(e, e.isTrigger);
        $("input").after(" Text marked!");
    });
    $("button").click(function(){
        $("input").trigger("select");
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>


<input type="text" value="Hello World"><br><br>

<button>Trigger the select event for the input field</button>

So, we have 1 isTrigger and 2 simple select events.

You can to filter isTrigger event, but can't to split two other - they are same.

Solution can be to not use trigger at all:

$(document).ready(function(){
    var mark = 0;
    $("input").select(function(e){
        if(!e.mark) e.mark = ++mark;
        console.log(e, e.mark);
        $("input").after(" Text marked!");
        e.stopImmediatePropagation();
    });
    $("button").click(function(){
        $("input")[0].setSelectionRange(0, $('input').val().length, 'forward');
      
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>


<input type="text" value="Hello World"><br><br>

<button>Trigger the select event for the input field</button>

But! We see it still triggered twice.
I think this bug should be reported to Chrome developers.


As solution - need modify your .select handler to be idempotent.
and say, on .blur reset this handler state.

like image 36
vp_arth Avatar answered Nov 10 '22 00:11

vp_arth


In IE and Firefox this works fine. Noticed the issue only in Chrome

This seems to be happen because the event gets bubbled up. If you inspect this using Developer tools you can see more information

enter image description here

If you inspect developer tools at last step breakpoint you can notice isTrigger attribute is true meaning it came from the trigger we have defined.

enter image description here

The next two hits of the same breakpoint of $("input").after(" Text marked!"); Developer tools shows almost similar set of attributes. Notice the bubbles attribute is true

enter image description here

like image 1
Nipuna Avatar answered Nov 09 '22 22:11

Nipuna