為什麼使用val()設置select的值時,jquery更改事件不會觸發?


當value val()val()設置時, change()事件處理程序中的邏輯沒有運行,但是當用戶用鼠標選擇一個值時,它會運行。 為什麼是這樣?

<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>

Answers



因為change事件需要由用戶發起的實際瀏覽器事件,而不是通過javascript代碼。

做這個,而不是:

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



我相信你可以用trigger()手動觸發change事件:

$("#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');



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

這適用於我的腳本。 我有3個組合和綁定與chainSelect事件,我需要傳遞3個值的網址和默認選擇所有下拉菜單。 我用這個

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

而第一個事件的工作。




我遇到同樣的問題,同時使用Wordpress的CMB2,並想掛鉤文件上傳元框的更改事件。

因此,如果您無法修改調用更改的代碼(在本例中為CMB2腳本),請使用下面的代碼。 觸發器被調用後,值設置,否則你的變化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);



如果你剛剛添加選擇選項到一個窗體,並希望觸發更改事件,我發現一個setTimeout是必需的,否則jQuery不拿起新添加的選擇框:

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