ฉันจะบังคับให้เหตุการณ์ onchange กับอินพุตโดยทางโปรแกรมได้อย่างไร


124

ฉันจะบังคับให้เหตุการณ์ onchange กับอินพุตโดยทางโปรแกรมได้อย่างไร

ฉันได้ลองทำสิ่งนี้แล้ว:

var code = ele.getAttribute('onchange');
eval(code);

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

คำตอบ:


145

สร้างEventวัตถุและส่งต่อไปยังdispatchEventวิธีการขององค์ประกอบ:

var element = document.getElementById('just_an_example');
var event = new Event('change');
element.dispatchEvent(event);

สิ่งนี้จะทริกเกอร์ผู้ฟังเหตุการณ์ไม่ว่าพวกเขาจะลงทะเบียนโดยการเรียกใช้addEventListenerเมธอดหรือโดยการตั้งค่าonchangeคุณสมบัติขององค์ประกอบ


หากคุณต้องการให้เหตุการณ์เกิดฟองคุณต้องส่งอาร์กิวเมนต์ที่สองไปยังตัวEventสร้าง:

var event = new Event('change', { bubbles: true });

ข้อมูลเกี่ยวกับความเข้ากันได้ของเบราว์เซอร์:



1
นี่คือวิธีการทำอย่างถูกต้องโดยกำเนิด รองรับในทุกเบราว์เซอร์แล้ว: caniuse.com/#feat=dispatchevent
Willem Mulder

1
นี่คือคำตอบที่แท้จริงสำหรับคำถามนี้ เราต้องบรรลุสิ่งนี้ด้วยวิธีที่ทันสมัย
КонстантинВан

1
ฉันพยายามทำสิ่งที่เทียบเท่าบน IE11 แต่ไม่ได้ผลเมื่อพยายามเปลี่ยนช่องป้อนข้อมูล reactjs var evt = document.createEvent('CustomEvent'); evt.initCustomEvent('input', true, false, { }); elem.dispatchEvent(evt);
Bodosko

3
ทำไมทุกคนถึงบอกว่านี่คือคำตอบที่ดีที่สุด? ตามเอกสารเหตุการณ์ที่เชื่อมโยงแม้แต่ IE เวอร์ชันปัจจุบันก็ยังไม่รองรับสิ่งนี้
jeff-h

96

ใน jQuery ส่วนใหญ่ฉันใช้:

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

2
tihs ช่วยฉันด้วย! ฉันกำลังตั้งค่าของช่องทำเครื่องหมาย (เลือกหรือไม่) โดยใช้รหัสและเหตุการณ์ไม่ได้เกิดขึ้นใน IE เลยไม่ว่าฉันจะทำอะไรก็ตาม ฉันลองเบลอ () โฟกัส () และอื่น ๆ อีกสองสามอย่าง หลังจากที่ฉันตั้งค่าที่ฉันเรียกว่าทริกเกอร์และฉันได้เพิ่มเหตุการณ์การคลิกเพื่อเรียกทริกเกอร์ด้วย มันทำให้เกิดไฟไหม้หลายครั้ง แต่มันไม่สำคัญสำหรับฉัน ใน IE ฉันเพิ่มช่องทำเครื่องหมายผ่านรหัสและคุณต้องคลิกสองครั้งก่อนที่เหตุการณ์การเปลี่ยนแปลงจะเริ่มขึ้น ขอบคุณสำหรับเคล็ดลับนี้
Dustin Davis

6
เป็นการอัพเดท $ ("# element"). change (); ทำสิ่งเดียวกันตั้งแต่ jquery 1.0
CookieOfFortune

3
โปรดทราบว่าสิ่งนี้ไม่ได้ทำให้เกิดการเปลี่ยนแปลงดั้งเดิม มันจะเริ่มทำงานกับผู้ฟัง onchange ทั้งหมดที่ถูกผูกไว้ผ่าน jQuery เท่านั้น!
Willem Mulder

กรุณาช่วยที่นี่? ดูเหมือนวิธีแก้ปัญหาเหล่านี้จะไม่ได้ผลสำหรับฉัน .. stackoverflow.com/questions/51216332/…
Gabe

60

ฮึไม่ได้ใช้ EVAL สำหรับอะไร มีบางอย่าง แต่หายากมาก แต่คุณจะทำสิ่งนี้:

document.getElementById("test").onchange()

ดูตัวเลือกเพิ่มเติมที่นี่: http://jehiah.cz/archive/firing-javascript-events-properly


3
ประเมินเพื่อคัดค้าน JSON;)
Aaron Powell

3
json2.js สำหรับการคัดค้าน JSON! JSON.parse พร้อมใช้งานแล้วบนเบราว์เซอร์สมัยใหม่
jinglesthula

12
เทคนิคนี้ใช้ได้เฉพาะเมื่อแนบตัวจัดการการเปลี่ยนแปลงโดยการตั้งค่า "onchange" ไม่สร้างเหตุการณ์ 'จริง' ที่ทริกเกอร์ w3c หรือ microsoft event handlers ดูลิงค์สำหรับรายละเอียดเพิ่มเติม
Stephen Nelson

6
ฉันคิดว่าคำตอบนี้ล้าสมัยไปแล้วดูเหมือนว่าคำตอบของ Miscreant ที่ใช้new Event(...)และdispatchEventเป็นทางออกที่เหมาะสมในปัจจุบัน
Jakub Holý

4
คำตอบนี้ไม่มีจำหน่ายแล้ว ; โค้ดด้านบนจะใช้ไม่ได้หากคุณใช้Element.addEventListenerจัดการเหตุการณ์ เพื่อให้บรรลุผลในรูปแบบที่ทันสมัยโปรดดูคำตอบของ @ Miscreant
КонстантинВан

23

ด้วยเหตุผลบางประการ ele.onchange () กำลังส่ง expception "ไม่พบวิธีการ" ให้ฉันใน IE บนหน้าเว็บของฉันดังนั้นฉันจึงใช้ฟังก์ชันนี้จากลิงก์ที่Koltenให้มาและเรียก fireEvent (ele, 'change') ซึ่งใช้งานได้ :

function fireEvent(element,event){
    if (document.createEventObject){
        // dispatch for IE
        var evt = document.createEventObject();
        return element.fireEvent('on'+event,evt)
    }
    else{
        // dispatch for firefox + others
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent(event, true, true ); // event type,bubbling,cancelable
        return !element.dispatchEvent(evt);
    }
}

อย่างไรก็ตามฉันได้สร้างหน้าทดสอบที่ยืนยันว่าการโทรควร onchange () ทำงาน:

<input id="test1" name="test1" value="Hello" onchange="alert(this.value);"/>
<input type="button" onclick="document.getElementById('test1').onchange();" value="Say Hello"/>

แก้ไข: สาเหตุที่ ele.onchange () ไม่ได้ผลเป็นเพราะฉันไม่ได้ประกาศอะไรเลยสำหรับเหตุการณ์ onchange แต่ fireEvent ยังคงทำงาน


2
ฉันชอบวิธีการตรวจจับเบราว์เซอร์นี้ (โดยการตรวจจับวัตถุ) ดีกว่าตัวอย่างที่ฉันให้ไว้
Chris MacDonald

สิ่งนี้ใช้ไม่ได้อีกต่อไปสำหรับ Firefox 23: "element.dispatchEvent ไม่ใช่ฟังก์ชัน"
Oliver

4
สวัสดีเพื่อน Googler มันคือปี 2016! ทุกวันนี้เราเขียนโค้ดเหมือนelement.dispatchEvent(new Event('change', true, true))แทนความลึกลับทั้งหมดและส่วนใหญ่เลิกใช้งานcreateEventและinitEventสิ่งต่างๆ
ericsoco

3

นี่คือคำตอบที่ถูกต้องที่สุดสำหรับ IE และ Chrome ::

javascript=>

var element = document.getElementById('xxxx');
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
element.dispatchEvent(evt);

2

นำมาจากด้านล่างของQUnit

function triggerEvent( elem, type, event ) {
    if ( $.browser.mozilla || $.browser.opera ) {
        event = document.createEvent("MouseEvents");
        event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
            0, 0, 0, 0, 0, false, false, false, false, 0, null);
        elem.dispatchEvent( event );
    } else if ( $.browser.msie ) {
        elem.fireEvent("on"+type);
    }
}

แน่นอนคุณสามารถแทนที่สิ่ง $ .browser เป็นวิธีการตรวจจับเบราว์เซอร์ของคุณเองเพื่อให้ jQuery เป็นอิสระ

ในการใช้ฟังก์ชันนี้:

var event;
triggerEvent(ele, "change", event);

โดยพื้นฐานแล้วสิ่งนี้จะทำให้เหตุการณ์ DOM จริงเหมือนกับว่ามีบางอย่างเปลี่ยนแปลงไปจริงๆ


1

หากคุณเพิ่มกิจกรรมทั้งหมดของคุณด้วยข้อมูลโค้ดนี้:

//put this somewhere in your JavaScript:
HTMLElement.prototype.addEvent = function(event, callback){
  if(!this.events)this.events = {};
  if(!this.events[event]){
    this.events[event] = [];
    var element = this;
    this['on'+event] = function(e){
      var events = element.events[event];
      for(var i=0;i<events.length;i++){
        events[i](e||event);
      }
    }
  }
  this.events[event].push(callback);
}
//use like this:
element.addEvent('change', function(e){...});

จากนั้นคุณสามารถใช้element.on<EVENTNAME>()ว่า<EVENTNAME>เป็นชื่อกิจกรรมของคุณได้ที่ไหนและจะเรียกเหตุการณ์ทั้งหมดด้วย<EVENTNAME>


-3

สำหรับการทริกเกอร์เหตุการณ์ใด ๆ ใน Javascript

 document.getElementById("yourid").addEventListener("change", function({
    //your code here
})

3
นี่คือการรับฟังเหตุการณ์ไม่ใช่กระตุ้นให้เกิดขึ้น
invalidusername

-4

หากคุณใช้ jQuery คุณจะมี:

$('#elementId').change(function() { alert('Do Stuff'); });

หรือ MS AJAX:

$addHandler($get('elementId'), 'change', function(){ alert('Do Stuff'); });

หรือใน HTML ดิบขององค์ประกอบ:

<input type="text" onchange="alert('Do Stuff');" id="myElement" />

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

$addHandler($get('elementId'), 'change', elementChanged);
function elementChanged(){
  alert('Do Stuff!');
}
function editElement(){
  var el = $get('elementId');
  el.value = 'something new';
  elementChanged();
}

เนื่องจากคุณเขียนเมธอด JavaScript อยู่แล้วซึ่งจะทำการเปลี่ยนแปลงจึงมีเพียง 1 บรรทัดเพิ่มเติมที่จะเรียก

หรือถ้าคุณกำลังใช้กรอบงาน Microsoft AJAX คุณสามารถเข้าถึงตัวจัดการเหตุการณ์ทั้งหมดผ่านทาง:

$get('elementId')._events

ช่วยให้คุณสามารถทำงานในลักษณะสะท้อนแสงเพื่อค้นหาตัวจัดการเหตุการณ์ที่เหมาะสมในการเริ่มทำงาน


1
ผมเชื่อว่าเขาต้องการที่จะยิงเหตุการณ์ที่เกิดขึ้นจริงไม่ได้เรียกใช้ฟังก์ชั่นเมื่อมีเหตุการณ์ยิง ... ฉันคิดว่า lol
Kolten

-5

การใช้ JQuery คุณสามารถทำสิ่งต่อไปนี้:

// for the element which uses ID
$("#id").trigger("change");

// for the element which uses class name
$(".class_name").trigger("change");

ไม่ได้กำหนดไม่ใช่ฟังก์ชัน
Hristo Venev
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.