Почему событие изменения jquery не запускается, когда я устанавливаю значение select с помощью 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>

9 ответов


- за change событие требует фактического события браузера, инициированного пользователем, а не с помощью кода javascript.

вместо этого:

$("#single").val("Single2").trigger('change');

или

$("#single").val("Single2").change();

Я верю, что вы можете вручную вызвать событие изменения с trigger():

$("#single").val("Single2").trigger('change');

хотя почему он не срабатывает автоматически, я понятия не имею.


насколько я могу читать в API. Событие запускается только тогда, когда пользователь нажимает на опцию.

http://api.jquery.com/change/

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


добавление этого фрагмента кода после val (), похоже, работает:

$(":input#single").trigger('change');

чтобы упростить добавление пользовательской функции и вызвать ее, когда вы хотите, чтобы изменение значения также вызывало изменение

$.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 и хотел подключиться к событию изменения файла загрузки metabox.

поэтому, если вы не можете изменить код, который вызывает изменение (в данном случае сценарий CMB2), используйте код ниже. Триггер вызывается после установки значения, в противном случае ваш change eventHandler будет работать, но значение будет предыдущим, а не заданным.

вот код, который я использую:

(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);

$(":input#single").trigger('change');

это работает для моего сценария. У меня есть 3 комбо и привязка с событием chainSelect, мне нужно передать 3 значения по url и по умолчанию выбрать все выпадающие. Я использовал это

$('#machineMake').val('<?php echo $_GET['headMake']; ?>').trigger('change');

и первое событие сработало.


Если вы только что добавили опцию select в форму и хотите вызвать событие change, я обнаружил, что setTimeout требуется, иначе jQuery не поднимет вновь добавленное поле выбора:

window.setTimeout(function() { jQuery('.languagedisplay').change();}, 1);