ChatGPT解决这个技术问题 Extra ChatGPT

当我使用 val() 设置选择的值时,为什么不触发 jquery 更改事件?

当值由 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>

M
Milind Anantwar

因为 change 事件需要用户发起的实际浏览器事件,而不是通过 javascript 代码。

改为这样做:

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

或者

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

嗨,做这个更新下拉。但被递归调用 onChange() 。
我挖掘这个答案。它可以工作,但是 jQuery 没有更好的方法吗?我敢肯定,每次我们更改设置了更改处理程序的值时(讽刺),我们都会记得这样做。使用数据绑定的框架可能会更好地解决这个问题?
@user113716 你知道如何在不知道任何值的情况下触发它吗?
我同意这是正确的答案,但这绝对很糟糕并破坏了我正在尝试做的事情。
试试 $("#single").trigger({type: "change", val: "Single2"})
D
David Thomas

我相信您可以使用 trigger() 手动触发更改事件:

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

虽然为什么它不会自动触发,但我不知道。


我无法得到这个工作,也 $("#single").val("Single2").change();我正在动态创建下拉列表并更改其值(它对我来说很好)但是当我尝试触发更改时它对我不起作用。
“有点”迟了,但它不会自动触发,因为它会导致无限循环。想想$('#foo').change(function() { $( this ).val( 'whatever' ); });
@Juhana 我认为无限循环比 val() 神秘地无法触发“更改”绑定更容易注意到、诊断和修复。
调用 .change() 是调用 .trigger('change') 的简写。
E
Eric Belair

在 val() 之后添加这段代码似乎有效:

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

是的,但您不需要使用 $(":input#single") 为它进行单独的 DOM 选择。事实上,你真的不应该。只需将其链接在 .val() 之后。您可以使用 .trigger('change').change()。它们完全相同。
M
Marnix

据我所知,API 的。该事件仅在用户单击选项时触发。

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

对于选择框、复选框和单选按钮,当用户使用鼠标进行选择时会立即触发该事件,但对于其他元素类型,该事件会延迟到元素失去焦点为止。


其他元素类型的替代方案是什么?我希望立即为 input 元素触发“更改”事件,而不是在元素失去焦点时触发。你知道吗?
如果“立即”是指“无论何时在输入中按下一个键”,那么您正在寻找 onkeyup、onkeypress 和 onkeydown 事件,而不是 onchange。
p
pbarney

为了使它更容易,添加一个自定义函数并在您想要更改值并触发更改时调用它:

$.fn.valAndTrigger = function (element) {
    return $(this).val(element).trigger('change');
}

$("#sample").valAndTrigger("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/ 的样品


我的浏览器抱怨递归太多,有什么解决办法吗?
您正在侦听控件上的 change 事件并执行回调,该回调(直接或间接)再次触发同一控件上的 change 事件。我建议您为手动触发的事件使用另一个名称(例如 explicit.change),这样它就不会重新触发 change 事件,防止循环,并且仍然允许您对事件做出反应.
c
codingrhythm

如果您不想与默认更改事件混淆,您可以提供自定义事件

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

D
Dave Hilditch

如果您刚刚将选择选项添加到表单并且希望触发更改事件,我发现需要 setTimeout 否则 jQuery 不会选择新添加的选择框:

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

u
user2075039

我在将 CMB2 与 Wordpress 一起使用时遇到了同样的问题,并想挂钩文件上传元框的更改事件。

因此,如果您无法修改调用更改的代码(在本例中为 CMB2 脚本),请使用以下代码。在设置值之后调用触发器,否则您的更改事件处理程序将起作用,但该值将是前一个,而不是正在设置的那个。

这是我使用的代码:

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

这很好,但你能展示你如何将它限制在一个特定的输入上吗?
@jwebb 不太清楚你的意思?我们重写了 jQuery val() 函数。您将更改事件处理程序绑定到特定输入。
我的意思是,@user2075039,如果页面上有多个使用 jQuery val() 函数的输入,并且您不想将自定义更改事件处理程序绑定到所有输入,而只是其中一个,该怎么办?
@jwebb,您可以在覆盖 $.fn.val 函数中检查 this.selector 以获取特定选择器(将取决于用于选择器的内容)。这是我发现的最好的仅针对特定字段执行此操作的方法,唯一的问题是您必须知道它们用于选择器的内容
T
Tom van der Woerdt
$(":input#single").trigger('change');

这适用于我的脚本。我有 3 个组合并与 chainSelect 事件绑定,我需要通过 url 传递 3 个值并默认选择所有下拉列表。我用这个

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

第一个事件奏效了。


我希望,你永远不会在现实世界中这样做。不用说 $_GET['whatever'] 是不可信的。