val()不会在jQuery中触发change()


342

change当我使用按钮更改事件值时,我试图在文本框上触发事件,但是它不起作用。检查这个小提琴

如果在文本框中键入内容,然后单击其他位置,change则会触发。但是,如果单击该按钮,则文本框的值将更改,但change不会触发。为什么?



标题本身回答了我的问题。确认为.change()黄色“注意:例如,使用JavaScript更改输入元素的值,例如使用.val()不会触发该事件。”
鲍勃·斯坦

希望我早日碰到stackoverflow.com/questions/11873721/…,希望对您有所帮助。
JeopardyTempest

Answers:


453

onchange 仅在用户键入输入时触发,然后输入失去焦点。

onchange设置值后,您可以使用手动调用事件:

$("#mytext").change(); // someObject.onchange(); in standard JS

或者,您可以使用以下方法触发事件:

$("#mytext").trigger("change");

18
随时扩展jquery并添加一个说valWithChange函数,它将执行您想要的操作。它不能是默认操作,因为您不希望多次从自动值更改中触发事件,仅当用户与元素进行交互时才会发生
redsquare 2010年

8
我希望看到编辑此答案以解决链接.change().val()方法的选项。
Snekse 2012年

19
原因可能是有些人因为进行输入验证而.val()进来.change()。触发.change().val()会导致无限循环。
yingted 2012年

7
仅当他们将值更改为无法通过自己的验证的情况时,这才是愚蠢的。

3
我最终blur不得不完成类似的任务:$('#mytext').focus().val('New text').blur();
Wes Johnson

63

根据redsquare的出色建议,这很好用:

$.fn.changeVal = function (v) {
    return this.val(v).trigger("change");
}

$("#my-input").changeVal("Tyrannosaurus Rex");

5
您不需要包裹thisreturn this.val(v).trigger("change");
一下

27

您可以val通过替换原始val功能的代理来轻松覆盖该功能以触发更改。

只需将此代码添加到文档中的某个位置(加载jQuery之后)

(function($){
    var originalVal = $.fn.val;
    $.fn.val = function(){
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0)
            $(this).change(); // OR with custom event $(this).trigger('value-changed');
        return result;
    };
})(jQuery);

工作示例:这里

(请注意,即使实际上未更改该值,也将始终changeval(new_val)调用when时触发。)

如果您只想在值实际更改时触发更改,请使用以下命令:

//This will trigger "change" event when "val(new_val)" called 
//with value different than the current one
(function($){
    var originalVal = $.fn.val;
    $.fn.val = function(){
        var prev;
        if(arguments.length>0){
            prev = originalVal.apply(this,[]);
        }
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0 && prev!=originalVal.apply(this,[]))
            $(this).change();  // OR with custom event $(this).trigger('value-changed')
        return result;
    };
})(jQuery);

实时示例:http : //jsfiddle.net/5fSmx/1/


4
嗯,不必要的鸭子打补丁,我想:-p。如redsquare所言,最好给该函数一个不同于的名称.val()
binki 2014年

1
如果重命名,则应更改现有代码-这样,您的现有代码将继续有效
Yaron U. 2014年

4
但是随后所有记入正确定义的代码.val()都会突然开始产生副作用:-p。
binki 2014年

2
这也会使插件发生故障,而
修复起来

1
为了避免副作用,我如上所述修改了val函数,但是我触发了一个不同的事件(“ val”),这使我可以保留现有代码,但可以在需要时轻松地进行处理:$(... ).on('change val',...)
ulu



8

看来事件并没有冒泡。尝试这个:

$("#mybutton").click(function(){
  var oldval=$("#mytext").val();
  $("#mytext").val('Changed by button');
  var newval=$("#mytext").val();
  if (newval != oldval) {
    $("#mytext").trigger('change');
  }
});

我希望这有帮助。

我只是尝试了一个普通的旧版本$("#mytext").trigger('change')而没有保存旧值,.change即使该值没有更改,也会触发火灾。这就是为什么我保存先前的值并$("#mytext").trigger('change')仅在其更改时才调用的原因。


感到惊讶的是,由于没有投票,因为这是HTML元素更改的当前有效实现。
vol7ron 2014年

4

从2019年2月开始.addEventListener(),jQuery .trigger()或当前不可用.change(),您可以在下面使用Chrome或Firefox对其进行测试。

txt.addEventListener('input', function() {
  console.log('not called?');
})
$('#txt').val('test').trigger('input');
$('#txt').trigger('input');
$('#txt').change();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="txt">

您必须使用.dispatchEvent()

txt.addEventListener('input', function() {
  console.log('it works!');
})
$('#txt').val('yes')
txt.dispatchEvent(new Event('input'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type="text" id="txt">


1

https://api.jquery.com/change/

change事件的值更改时,该事件将发送到该元素。此事件仅限于<input>元素,<textarea>框和<select>元素。对于选择框,复选框和单选按钮,当用户使用鼠标进行选择时会立即触发该事件,但是对于其他元素类型,该事件将推迟到该元素失去焦点之前。


1

我知道这是一个旧线程,但是对于其他人来说,上述解决方案可能不如以下解决方案好,而不是检查change事件,而是检查input事件。

$("#myInput").on("input", function() {
    // Print entered value in a div box
    $("#result").text($(this).val());
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.