为什么我的自定义jQuery`change`事件被触发两次?

时间:2016-09-05 13:02:21

标签: javascript jquery

我是trying to make jQuery兼容的复合HTML输入。

select更改alert时,<span id="x"></span> 会被调用两次。为什么呢?

给出一个简单的容器节点:

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

这是一个完全有效的演示:

<?php

$regex = '~\(\h*([\'"])(.+?)\h*(?!\\\\)(?=\1)~';
$string = "Backbone.Radio( 'comments ').trigger(\"added:comment \" ,function(){});";

preg_match_all($regex, $string, $matches);
print_r($matches[2]);
/*
Array
(
    [0] => comments
    [1] => added:comment
)
*/
?>

2 个答案:

答案 0 :(得分:3)

因为当您在下拉列表中更改值时,它会更改父元素drom结构。这意味着你正在改变A和B的价值它的A和B的专利是X所以它会自动改变所以你必须停止事件传播

您必须删除以下代码

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

或者您必须使用preventDefault();

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

答案 1 :(得分:0)

Does the onchange event propagate?

jQuery documentation表明此事件仅适用于输入,选择和textarea,在任何情况下,正在发生的事情是传播(气泡)到父元素。

如果停止传播,将起作用:

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

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