以编程方式选择一个选项时,“ on change”不会触发

时间:2018-10-26 15:17:17

标签: javascript jquery html

我有一个CodePen,它在选择了cities之后加载了country ...,现在用//$("#country").val("3");代码注释了“手动”更改coutry的效果很好。

但是country的“自动”(未注释代码)负载不会改变城市……为什么?

PS。我不想手动触发“更改”事件。对我来说很奇怪,我应该手工做...

document.addEventListener("DOMContentLoaded", function(event) {

var countries = {
  "1": ["Paris", "Lyon"],
  "2": ["Berlin", "Cologne"],
  "3": ["London", "Edinburgh"]
};

function loadCities(countryId) {
  var cities = countries[countryId];
  var container = "#city";
  $(container).empty();
  $(container).append($("<option/>", { value: 0, text: "select a city..." }));
  $.each(cities, function(key, city) {
    $(container).append($("<option/>", { text: city }));
  });
}

$("#country").on("change", function() {
  var countryId = $(this).val();
  loadCities(countryId);
});

$("#country").val("3");//.trigger("change");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="country">
  <option value="0">select a country</option>
  <option value="1">France</option>
  <option value="2">Germany</option>
  <option value="3">UK</option>
</select>
<select id="city">
  <option value="0">no country selected</option>
</select>

3 个答案:

答案 0 :(得分:3)

如果您不想“触发更改”,则始终可以自行调用该函数。

function selectCountry(countryId) {
    $("#country").val(countryId);
    loadCities(countryId)
}

然后替换为:

$("#country").val("3");//.trigger("change");

与此:

selectCountry("3")

答案 1 :(得分:2)

您还必须触发change事件,如下所示:

$("#country").val("3");
$("#country").trigger("change");

onchange仅在用户键入输入内容时触发,然后输入内容失去焦点。它不是您不想让自动值更改触发事件的多次默认操作,仅当用户与元素进行交互时才可以。

原因可能是某些人因为进行输入验证而在.val()中叫.change()。在.change()上触发.val()会导致无限循环。

答案 2 :(得分:1)

document.addEventListener("DOMContentLoaded", function(event) {
  var cities = {
    "1": ["Paris", "Lyon"],
    "2": ["Berlin", "Cologne"],
    "3": ["London", "Edinburgh"]
  };

  function loadCities(countryId) {
    //get the city names if we can
    var cityNames = cities[countryId];
    //get a reference to the container
    var $container = $('#city');
    //create an array of the options we want to replace the city with
    //building a list of the options allows us to optimize in two ways
    //1) Not using jQuery to create the options removes some overhead with
    //   jQuery creating the DOM nodes one at a time
    //2) Replacing all the options at the end reduces the number of times
    //   you manipulate the DOM and reduce the number of times it has to
    //   perform calculations about how it is going to re-draw the page
    var options = ['<option value="0">select a city...</option>'];
    
    //we will have cityNames if the countryId is not 0
    if (cityNames) {
      //make an option for each city
      cityNames.forEach(function(city){
        options.push('<option>'+ city +'</option>');
      });
    } else {
      //user did not select a country, default the city back to the original
      //message
      options = ['<option value="0">no country selected</option>'];
    }
    
    //replace all the options with the new options.  This will be a single
    //DOM change
    $container.html(options);
  }

  $("#country")
    //bind the on change like we were before
    .on("change", function() {
      var countryId = $(this).val();
      loadCities(countryId);
    })
    //also change the value
    .val("3");
  //call loadCities directly to update the city dropdown
  loadCities("3");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="country">
  <option value="0">select a country</option>
  <option value="1">France</option>
  <option value="2">Germany</option>
  <option value="3">UK</option>
</select>
<select id="city">
  <option value="0">no country selected</option>
</select>