Почему событие изменения jquery не срабатывает, когда я устанавливаю значение выбора с помощью val()?
Логика в change()
обработчик событий не запускается, когда значение установлено val()
, но он работает, когда пользователь выбирает значение с помощью мыши. Почему это?
<select id="single">
<option>Single</option>
<option>Single2</option>
</select>
<script>
$(function() {
$(":input#single").change(function() {
/* Logic here does not execute when val() is used */
});
});
$("#single").val("Single2");
</script>
10 ответов
Поскольку change
Событие требует фактического события браузера, инициированного пользователем, а не через код JavaScript.
Сделайте это вместо этого:
$("#single").val("Single2").trigger('change');
или же
$("#single").val("Single2").change();
Я считаю, что вы можете вручную вызвать событие изменения с trigger()
:
$("#single").val("Single2").trigger('change');
Хотя почему он не срабатывает автоматически, я понятия не имею.
Добавление этого фрагмента кода после val(), кажется, работает:
$(":input#single").trigger('change');
Насколько я могу прочитать в API. Событие запускается только тогда, когда пользователь нажимает на опцию.
Для полей выбора, флажков и переключателей событие вызывается немедленно, когда пользователь делает выбор с помощью мыши, но для других типов элементов событие откладывается до тех пор, пока элемент не потеряет фокус.
Для упрощения добавьте пользовательскую функцию и вызывайте ее, когда захотите, чтобы изменение значения также вызывало изменение
$.fn.valAndTrigger = function (element) {
return $(this).val(element).trigger('change');
}
а также
$("#sample").valAndTirgger("NewValue");
Или вы можете переопределить функцию val, чтобы всегда вызывать изменение при вызове val
(function ($) {
var originalVal = $.fn.val;
$.fn.val = function (value) {
this.trigger("change");
return originalVal.call(this, value);
};
})(jQuery);
Образец на http://jsfiddle.net/r60bfkub/
Если вы не хотите смешиваться с событием изменения по умолчанию, вы можете указать свое собственное событие.
$('input.test').on('value_changed', function(e){
console.log('value changed to '+$(this).val());
});
чтобы вызвать событие на заданном значении, вы можете сделать
$('input.test').val('I am a new value').trigger('value_changed');
Я столкнулся с той же проблемой при использовании CMB2 с Wordpress и хотел подключиться к событию изменения метабокса загрузки файла.
Поэтому, если вы не можете изменить код, который вызывает изменение (в данном случае сценарий CMB2), используйте код ниже. Триггер вызывается ПОСЛЕ установки значения, в противном случае ваш changeHandler изменения будет работать, но значение будет предыдущим, а не установленным.
Вот код, который я использую:
(function ($) {
var originalVal = $.fn.val;
$.fn.val = function (value) {
if (arguments.length >= 1) {
// setter invoked, do processing
return originalVal.call(this, value).trigger('change');
}
//getter invoked do processing
return originalVal.call(this);
};
})(jQuery);
Если вы только что добавили опцию выбора в форму и хотите запустить событие изменения, я обнаружил, что требуется setTimeout, иначе jQuery не подхватит вновь добавленное поле выбора:
window.setTimeout(function() { jQuery('.languagedisplay').change();}, 1);
$(":input#single").trigger('change');
Это сработало для моего сценария. У меня есть 3 комбо и связывание с событием chainSelect, мне нужно передать 3 значения по URL и по умолчанию выбрать все выпадающее меню. Я использовал это
$('#machineMake').val('<?php echo $_GET['headMake']; ?>').trigger('change');
И первое событие сработало.
Чтобы изменить значение
$("#single").val("Single2");
Также для запуска события изменения
$("#single").val("Single2").change();
эта логика полезна, когда на странице есть несколько вариантов выбора.
один изменяется, а другие параметры выбора должны изменяться, но не вызывают событие изменения.