Reputation: 33425
I am trying to make a jQuery-compatible composite HTML input.
In this example when either select
changes, the alert
is invoked twice. Why?
Given a simple container node:
<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');});
Upvotes: 5
Views: 78
Reputation: 8287
Does the onchange event propagate?
The jQuery documentation suggests that this event applies only to inputs, selects and textarea, in any case, what is happening is propagation (bubble) to the parent element.
If you stop the propagation, 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();
});
Upvotes: 0
Reputation: 8496
Its because when you are change value in dropdown it change parent evelement drom structure. it means you are changing value of A an B it patent of A and B is X so it change automatically so you have to stop event propagation
you have to remove below code
$(a) .change (function () {$(x) .trigger ('change');});
$(b) .change (function () {$(x) .trigger ('change');});
or you have 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; });
Upvotes: 3