val () ไม่เรียกการเปลี่ยนแปลง () ใน jQuery


343

ฉันพยายามที่จะทริกเกอร์changeเหตุการณ์บนกล่องข้อความเมื่อฉันเปลี่ยนค่าด้วยปุ่ม แต่มันไม่ทำงาน ตรวจสอบซอนี้

หากคุณพิมพ์บางอย่างในกล่องข้อความและคลิกที่อื่นchangeจะถูกเรียกใช้ อย่างไรก็ตามหากคุณคลิกปุ่มค่ากล่องข้อความจะเปลี่ยนไป แต่changeจะไม่มีการกระตุ้น ทำไม?


2
มีความเป็นไปได้ที่ซ้ำกันของjQuery textbox.val ('xxxx') ไม่ทำให้เกิดการเปลี่ยนแปลง

ชื่อตัวเองตอบคำถามของฉัน ยืนยันที่. change () yellow "หมายเหตุ: การเปลี่ยนค่าของอิลิเมนต์อินพุตโดยใช้ JavaScript โดยใช้. val () ตัวอย่างเช่นจะไม่เริ่มการทำงานของเหตุการณ์"
Bob Stein

หวังว่าฉันจะเจอstackoverflow.com/questions/11873721/หวังว่ามันจะช่วยได้บ้าง
JeopardyTempest

คำตอบ:


454

onchange จะยิงก็ต่อเมื่อผู้ใช้พิมพ์ลงในอินพุตจากนั้นอินพุตจะสูญเสียโฟกัส

คุณสามารถเรียกonchangeเหตุการณ์ด้วยตนเองโดยใช้หลังจากตั้งค่า:

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

หรือคุณสามารถทริกเกอร์เหตุการณ์โดยใช้:

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

18
อย่าลังเลที่จะขยาย jquery และเพิ่มฟังก์ชั่นพูด valWithChange ที่จะทำสิ่งที่คุณต้องการ มันไม่สามารถเป็นการกระทำเริ่มต้นได้หลายครั้งที่คุณไม่ต้องการให้เหตุการณ์เกิดขึ้นจากการเปลี่ยนแปลงค่าอัตโนมัติเฉพาะเมื่อผู้ใช้โต้ตอบกับองค์ประกอบ
redsquare

8
ฉันต้องการจะดูคำตอบนี้แก้ไขเพื่อที่อยู่ตัวเลือกของการผูกมัด.change()กับ.val()วิธีการ
Snekse

19
สาเหตุอาจเป็นได้ว่าบางคนโทร.val()เข้า.change()เพราะพวกเขาทำการตรวจสอบอินพุต ทริกเกอร์.change()บน.val()จะทำให้เกิดวง จำกัด
yingted

7
เฉพาะในกรณีที่พวกเขาเปลี่ยนค่าเป็นสิ่งที่จะล้มเหลวในการตรวจสอบของตัวเองซึ่งจะโง่
เล้ง

3
ฉันสิ้นสุดผูกพันกับblurที่จะบรรลุสิ่งที่คล้ายกัน:$('#mytext').focus().val('New text').blur();
เวสจอห์นสัน

63

จากคำแนะนำที่ยอดเยี่ยมของ redsquare สิ่งนี้ได้ผลดี:

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

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

5
คุณไม่จำเป็นต้องห่อthis:return this.val(v).trigger("change");
นาย Polywhirl

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

ตัวอย่างการทำงาน: ที่นี่

(โปรดทราบว่าสิ่งนี้จะทริกเกอร์เสมอchangeเมื่อval(new_val)ถูกเรียกแม้ว่าค่าจะไม่เปลี่ยนแปลงจริง ๆ )

หากคุณต้องการที่จะทริกเกอร์การเปลี่ยนแปลงเฉพาะเมื่อค่าจริงเปลี่ยนให้ใช้สิ่งนี้:

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

1
หากคุณเปลี่ยนชื่อคุณควรเปลี่ยนรหัสที่มีอยู่ - วิธีนี้รหัสที่มีอยู่ของคุณจะทำงานต่อไปได้
Yaron U.

4
แต่แล้วรหัสทั้งหมดที่เขียนด้วยคำจำกัดความที่ถูกต้องของ.val()ในใจก็จะเริ่มผลิตผลข้างเคียง :-p
binki

2
สิ่งนี้จะทำให้ปลั๊กอินทำงานผิดพลาดซึ่งอาจไม่สามารถแก้ไขได้อย่างง่ายดาย
ดังนั้น

1
เพื่อหลีกเลี่ยงผลข้างเคียงฉันได้แก้ไขฟังก์ชั่น val ข้างต้น แต่ฉันเรียกเหตุการณ์ที่แตกต่าง ("val") ซึ่งช่วยให้ฉันเก็บรหัสที่มีอยู่ แต่จัดการได้อย่างง่ายดายทุกครั้งที่ต้องการ: $ (... ) .on ('เปลี่ยน 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

4

ตั้งแต่ feb 2019 .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());
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.