val () không kích hoạt thay đổi () trong jQuery


342

Tôi đang cố gắng kích hoạt changesự kiện trên hộp văn bản khi tôi thay đổi giá trị của nó bằng một nút, nhưng nó không hoạt động. Kiểm tra fiddle này .

Nếu bạn nhập nội dung nào đó vào hộp văn bản và nhấp vào nơi khác, changesẽ được kích hoạt. Tuy nhiên, nếu bạn nhấp vào nút, giá trị hộp văn bản sẽ thay đổi, nhưng changekhông kích hoạt. Tại sao?


2
sao chép có thể của văn bản jQuery.val ('xxxx') không gây ra thay đổi?

Tiêu đề tự trả lời câu hỏi của tôi. Xác nhận tại .change () màu vàng "Lưu ý: Thay đổi giá trị của phần tử đầu vào bằng JavaScript, ví dụ sử dụng .val (), sẽ không kích hoạt sự kiện."
Bob Stein

Ước gì tôi đã đi qua stackoverflow.com/questions/11873721/ , sớm hơn, hy vọng nó sẽ giúp một số.
JeopardyTempest

Câu trả lời:


453

onchange chỉ kích hoạt khi người dùng gõ vào đầu vào và sau đó đầu vào mất tiêu điểm.

Bạn có thể gọi thủ công onchangesự kiện bằng cách sử dụng sau khi đặt giá trị:

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

Ngoài ra, bạn có thể kích hoạt sự kiện bằng cách sử dụng:

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

18
vui lòng mở rộng jquery và thêm chức năng nói valWithChange sẽ làm những gì bạn muốn. Nó không thể là hành động mặc định vì nhiều lần bạn không muốn sự kiện kích hoạt từ thay đổi giá trị tự động, chỉ khi người dùng tương tác với phần tử
redsapes

8
Tôi muốn xem câu trả lời này được chỉnh sửa để giải quyết tùy chọn xâu chuỗi .change()cho .val()phương thức.
Snekse

19
Lý do có thể là một số người gọi .val()trong .change()vì họ làm xác nhận đầu vào. Kích hoạt .change()trên .val()sẽ gây ra một vòng lặp vô hạn.
kéo dài

7
Chỉ khi họ thay đổi giá trị thành thứ gì đó sẽ không xác nhận chính họ, điều đó thật ngớ ngẩn.
Leng

3
Cuối cùng tôi đã ràng buộc để blurhoàn thành một cái gì đó tương tự:$('#mytext').focus().val('New text').blur();
Wes Johnson

63

Từ đề xuất tuyệt vời của redsapes, điều này hoạt động độc đáo:

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

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

5
Bạn không cần phải bọc this:return this.val(v).trigger("change");
Ông Polywhirl

27

Bạn có thể dễ dàng ghi đè valchức năng để kích hoạt thay đổi bằng cách thay thế nó bằng proxy thành valchức năng ban đầu .

chỉ cần thêm mã này vào đâu đó trong tài liệu của bạn (sau khi tải 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);

Một ví dụ làm việc: ở đây

(Lưu ý rằng điều này sẽ luôn kích hoạt changekhi val(new_val)được gọi ngay cả khi giá trị không thực sự thay đổi.)

Nếu bạn muốn kích hoạt thay đổi CHỈ khi giá trị thực sự thay đổi, hãy sử dụng giá trị này:

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

Ví dụ trực tiếp cho điều đó: http://jsfiddle.net/5fSmx/1/


4
Hmm, vá vịt không cần thiết, tôi nghĩ :-p. Có thể tốt hơn, như nhận xét của redsapes , cung cấp cho một chức năng như vậy một tên khác hơn .val().
binki

1
Nếu bạn đổi tên, bạn nên thay đổi mã hiện tại - theo cách này, mã hiện tại của bạn sẽ tiếp tục hoạt động
Yaron U.

4
Nhưng sau đó, tất cả các mã được viết với định nghĩa chính xác .val()trong tâm trí sẽ đột nhiên bắt đầu tạo ra các tác dụng phụ :-p.
binki

2
Điều này cũng sẽ làm cho plugin trục trặc, mà có thể không được như dễ dàng fixable
SoWhat

1
Để tránh tác dụng phụ, tôi đã sửa đổi hàm val như trên, nhưng tôi đang kích hoạt một sự kiện khác ("val"), cho phép tôi giữ mã hiện có nhưng dễ dàng xử lý bất cứ khi nào tôi cần: $ (... ) .on ('thay đổi val', ...)
ulu


14

Không, bạn có thể cần kích hoạt thủ công sau khi đặt giá trị:

$('#mytext').change();

hoặc là:

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

8

Có vẻ như các sự kiện không sủi bọt. Thử cái này:

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

Tôi hi vọng cái này giúp được.

Tôi đã thử chỉ là một cái cũ đơn giản $("#mytext").trigger('change')mà không lưu giá trị cũ, và các .changeđám cháy ngay cả khi giá trị không thay đổi. Đó là lý do tại sao tôi đã lưu giá trị trước đó và $("#mytext").trigger('change')chỉ gọi nếu nó thay đổi.


Thật ngạc nhiên khi điều này không có nhiều phiếu bầu hơn, vì đây là cách thực hiện hiệu quả thay đổi thành phần HTML hiện tại.
vol7ron

4

Kể từ feb 2019 .addEventListener()hiện không hoạt động với jQuery.trigger() hoặc .change(), bạn có thể kiểm tra nó bên dưới bằng Chrome hoặc 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">

bạn phải sử dụng .dispatchEvent()thay thế.

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

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

Sự changekiện được gửi đến một phần tử khi giá trị của nó thay đổi. Sự kiện này được giới hạn cho <input>các yếu tố, <textarea>hộp và <select>các yếu tố. Đối với các hộp chọn, hộp kiểm và nút radio, sự kiện sẽ được kích hoạt ngay lập tức khi người dùng thực hiện lựa chọn bằng chuột, nhưng đối với các loại phần tử khác, sự kiện được hoãn lại cho đến khi phần tử mất tiêu điểm.


1

Tôi biết đây là một chủ đề cũ, nhưng đối với những người khác đang tìm kiếm, các giải pháp trên có thể không tốt như sau, thay vì kiểm tra changecác sự kiện, hãy kiểm tra các inputsự kiện.

$("#myInput").on("input", function() {
    // Print entered value in a div box
    $("#result").text($(this).val());
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.