"при изменении" не срабатывает при программном выборе параметра

У меня есть CodePen, который загружает cities после выбора country ..., теперь с кодом //$("#country").val("3"); прокомментировано "ручное" изменение страны работает хорошо.

А вот "автоматическая" (код без комментариев) загрузка 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>

у вас происходит странная смесь js и jQuery - что происходит, когда вы меняете первую строку на: jQuery(document).ready(function($) {

treyBake 26.10.2018 17:21

Возможный дубликат val () не запускает change () в jQuery

Peter B 26.10.2018 17:23

Если вы запустите свой сниппет, появится ошибка "Uncaught ReferenceError: $ is not defined". Если вы измените свой фрагмент на более новую версию jQuery, например 2.x.x, ваш код будет работать. Попробуйте изменить версию jQuery в своем фрагменте.

Alexander Staroselsky 26.10.2018 17:23

@PeterB: Я не хочу вручную запускать «изменение».

serge 26.10.2018 17:24

@Serge Вы должны. Логические изменения не создают событий. События предназначены для взаимодействия с пользователем. Это объясняется в дубликате

Taplar 26.10.2018 17:24

@AlexanderStaroselsky: пожалуйста, посмотрите Codepen, странно, почему он не работает, jquery не загружается ...

serge 26.10.2018 17:25

@Serge, мой первый комментарий к этой теме исправит проблему с ReferenceError.

treyBake 26.10.2018 17:30

Пользователь @ Sv443 сделал глупую правку, нарушившую орфографию Edinburgh +, которая удалила библиотеку jQuery. Слишком поздно делать откат, потому что вы уже внесли правку поверх нее (которая затем также будет отменена) ...

Peter B 26.10.2018 17:32

@PeterB обновил фрагмент

serge 26.10.2018 17:34

@ThisGuyHasTwoThumbs исправлено применением предложения Александра

serge 26.10.2018 17:35

Ничего не сломал. Я просто удалил тег сценария jQuery, потому что он автоматически включен

Sv443 26.10.2018 17:35

@ Sv443 в чем проблема с "Эдинбургом"?

serge 26.10.2018 17:37

Боковая точка. $.each не нужен. Ключ ваших городов - это ваш countryId. Можно просто cities[countryId]

Taplar 26.10.2018 17:38

@Serge Я ничего не изменил. Как я уже сказал, я сделал только одно редактирование, и это заключалось в удалении первой строки в разделе HTML, и я изменил версию jQuery в настройках фрагмента. Я даже больше ни на что не нажимал.

Sv443 26.10.2018 17:39

Я только что посмотрел исправления, и вы правы, я как-то это изменил. Не знаю, как это случилось, но ладно.

Sv443 26.10.2018 17:47

@Taplar для ваших городов [countryId] »отметьте знак« == », это означает, что если ключи являются целыми числами, мы должны сравнивать их по значению, а не по типу ...

serge 26.10.2018 17:51

Единственная причина, по которой вы это делаете, заключается в том, что вы просматриваете все записи в объекте и пытаетесь найти тот, у которого есть города для countryId. Но это объект. Вы не должны делать это. CountryId - это ключ объекта. Я использовал этот факт в своем ответе ниже

Taplar 26.10.2018 17:53

@Taplar я делаю это, потому что в моем реальном примере я получаю целые числа из json в качестве идентификатора, но использую строки в качестве ключа, поэтому «2» и 2 - это не одно и то же, я должен сравнивать «==», а не «===»

serge 26.10.2018 18:00

то countryId.toString() исправит это. Нет необходимости в петле

Taplar 26.10.2018 18:00

@Taplar хороший момент ...

serge 26.10.2018 18:00
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
20
73
3

Ответы 3

Вы также должны вызвать событие change, например:

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

onchange срабатывает только тогда, когда пользователь вводит ввод, а затем ввод теряет фокус. Это не может быть действием по умолчанию, поскольку вы не хотите, чтобы событие запускалось из-за автоматического изменения значения, только когда пользователь взаимодействует с элементом.

Причина может заключаться в том, что некоторые люди вызывают .val() в .change(), потому что они выполняют проверку ввода. Запуск .change() на .val() вызовет бесконечный цикл.

Ну, я бы хотел использовать событие "select", может быть ... вместо "change"

serge 26.10.2018 17:27

вы можете расширить jquery и добавить функцию, скажем, valWithChange, которая будет делать то, что вы хотите.

Tudor Constantin 26.10.2018 17:29

Или используйте пространство имен, например change.country.

Jonathan Rys 26.10.2018 17:30

Вы также можете написать это как: $("#country").val("3").change();

Jonathan Rys 26.10.2018 17:31

Если вы не хотите «инициировать изменение», вы всегда можете вызвать функцию самостоятельно.

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

затем замените это:

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

с этим:

selectCountry("3")

На самом деле это предпочтительнее, так как вы не пропустите свою логику через dom. Вы идете прямо к тому, что хотите делать.

Taplar 26.10.2018 17:32

@dovidweisz, просто покажите, пожалуйста, как включить его в реальный код;)

serge 26.10.2018 18:54

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>

хорошо, но я хочу, чтобы мой "val (" 3 ")" автоматически обновлял значения, если это возможно .. не должно быть необходимости вызывать "loadCities (" 3 ");"

serge 26.10.2018 17:55

Это уже объяснялось тем фактом, что логические изменения не создают событий.

Taplar 26.10.2018 17:56

мое логическое изменение обновляет выбранное значение и текст элемента select. это событие для меня ...

serge 26.10.2018 17:57

Это не событие для javascript. Вы должны работать с языком.

Taplar 26.10.2018 17:58

Другие вопросы по теме