¿Por qué mi evento jQuery `change` personalizado se desencadena dos veces?

Estoy tratando de hacer una input HTML compuesta compatible con jQuery.

En este ejemplo, cuando se select cambios, la alert se invoca dos veces. ¿Por qué?

Dado un nodo contenedor simple:

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

Aquí hay una demostración completamente funcional:

 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');}); 

Es porque cuando cambias el valor en el menu desplegable, cambias la estructura drom de evelement padre. significa que está cambiando el valor de A y B, la patente de A y B es X, por lo que cambia automáticamente, por lo que debe detener la propagación del evento

tienes que eliminar el código debajo

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

o tiene que usar preventDefault ();

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

¿El evento onchange se propaga?

La documentation de jQuery sugiere que este evento se aplica solo a inputs, selects y área de text, en cualquier caso, lo que está sucediendo es propagación (burbuja) al elemento padre.

Si detiene la propagación, funcionará:

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