开发者问题收集

多个元素的一个更改事件,运行一次函数

2016-02-09
867

HTML

<label>
  <select id="foo">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
  </select>
</label>

<label>
  <select id="bar">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
  </select>
</label>

<label>
  <select id="foobar">
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
  </select>
</label>

Jquery

$(document).on("change", "#foo, #bar, #foobar", function(){
    $("#bar").val($("#foo").val()).trigger("change");
  /* Do something for #foo & #bar*/

  /* Run this when all changes are done */
    console.log("done");
})

问题 运行上述代码时,我收到 Uncaught RangeError: Maximum call stack size reached ,我的理解是,因为 change 事件会无限重复。

如何避免这种情况? 我有这些元素的通用 Change 代码,它们都需要在最后运行相同的函数,但仅在触发所有 Change 事件后才运行。 注意: .trigger("change") 是必需的,我过度简化了代码。

JSFiddle here

编辑 添加了与我已有代码更相似的代码。

3个回答

使用 one 代替 on,如下所示

$(document).one("change", "#foo, #bar", function(){
    $("#bar").val($("#foo").val()).trigger("change");
  /* Do something for #foo & #bar*/

  /* Run this when all changes are done */
    console.log("done");
})
Thangaraja
2016-02-09

就我个人而言,我会考虑使用 Javascripts requestAnimationFrame()。这有点像作弊,但可以让您无限次地检查,而无需锁定浏览器。

我甚至会考虑将 @Thangaranja 的部分答案与此结合起来。例如(将“one”替换为“on”);

function check_changes(){
  $(document).on("change", "#foo, #bar", function(){
    $("#bar").val($("#foo").val()).trigger("change");
    * Do something for #foo & #bar*/

    /* Run this when all changes are done */
    console.log("done");
  })
}

requestAnimationFrame(check_changes);

这是一个未经测试的想法,但可能对您有用。

Someone
2016-02-09

由于您是通过 ajax 获取新选项的,因此我建议将字段名称和值传递给此函数,如下所示。您需要更改字段名称,但这应该是有意义的。

onChange="menuChange('fieldname', this.value)"

function menuChange(field, value){


    switch(field){

        case "class":
        document.getElementById("class").options.length = 0;
        document.getElementById("category").options.length = 1;
        document.getElementById("subcategory").options.length = 1;
        break;

        case "category":
        document.getElementById("category").options.length = 0;
        document.getElementById("subcategory").options.length = 1;
        break;

        case "subcategory":
        document.getElementById("subcategory").options.length = 0;
        break;

    }
    document.getElementById(field).options.length = 0;

    $.ajax({
        url: "ajaxrequest.php",
        type: "post",
        data: { field: field,
              value: value },
        success: function (response) {

           console.log(response);
           document.getElementById(field).innerHTML = response;               

        },
        error: function(jqXHR, textStatus, errorThrown) {
           console.log(textStatus, errorThrown);
        }


    });



}

只需将其放入图像中:

首先填充组,然后填充其他内容,当组更改时,类将使用组的值进行更新,当类更改时,类别将使用类的值进行更新.........

image

Adam Copley
2016-02-09