Why is my jQuery "change" custom event fired twice?

I am trying to make jQuery compatible HTML composite input.

In this example , when either select changes, alert is called twice. Why?

For a simple node container:

 <span id="x"></span> 

Here is a fully working demo:

 function el (type) { return document .createElement (type); } function opt (sel, value) { let node = el ('option'); node .value = value; node .appendChild (document .createTextNode (value)); sel .appendChild (node); } let x = document .getElementById ('x'); let a = el ('select'); let b = el ('select'); x .appendChild (a); x .appendChild (b); opt (a, 'a_1'); opt (a, 'a_2'); opt (b, 'b_1'); opt (b, 'b_2'); $(a) .change (function () {$(x) .trigger ('change');}); $(b) .change (function () {$(x) .trigger ('change');}); $(x) .change (function () {alert ('changed');}); 
+5
source share
2 answers

Because when you change the value in the drop-down list, it changes the structure of the drom child. this means that you are changing the value of A a B, this is patent A and B is X, so it automatically changes, so you need to stop the distribution of events.

you need to remove below code

 $(a) .change (function () {$(x) .trigger ('change');}); $(b) .change (function () {$(x) .trigger ('change');}); 

or you need to use preventDefault ();

 $(a) .change (function (e) {e.preventDefault(); $(x) .trigger ('change'); return false; }); $(b) .change (function (e) {e.preventDefault(); $(x) .trigger ('change'); return false; }); 
+3
source

Is an onchange event happening?

The jQuery documentation suggests that this event only applies to inputs, selects and textarea, in any case what happens is the propagation (bubble) to the parent element.

If you stop the distribution, it will work:

 $(a) .change (function (event) { $(x) .trigger ('change'); console.log('a'); event.stopPropagation(); }); $(b) .change (function (event) { $(x) .trigger ('change'); console.log('b'); event.stopPropagation(); }); 
0
source

All Articles