ตัวสร้างเหตุการณ์ของ Internet Explorer 9, 10 & 11 ไม่ทำงาน


129

ฉันกำลังสร้างกิจกรรมใช้ตัวสร้างเหตุการณ์ DOM:

new Event('change');

สิ่งนี้ทำงานได้ดีในเบราว์เซอร์ที่ทันสมัยอย่างไรก็ตามใน Internet Explorer 9, 10 & 11 มันล้มเหลวด้วย:

Object doesn't support this action

ฉันจะแก้ไข Internet Explorer (ผ่านโพลีฟิล) ได้อย่างไร? หากฉันไม่สามารถทำได้ฉันสามารถใช้วิธีแก้ไขปัญหาได้หรือไม่


55
"ฉันจะแก้ไข Internet Explorer ได้อย่างไร" xD
contactmatt

คำตอบ:


176

มีความเป็นpolyfill IE สำหรับคอนสตรัค CustomEvent ที่ MDN การเพิ่ม CustomEvent ให้กับ IE และใช้งานแทน

(function () {
  if ( typeof window.CustomEvent === "function" ) return false; //If not IE

  function CustomEvent ( event, params ) {
    params = params || { bubbles: false, cancelable: false, detail: undefined };
    var evt = document.createEvent( 'CustomEvent' );
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
    return evt;
   }

  CustomEvent.prototype = window.Event.prototype;

  window.CustomEvent = CustomEvent;
})();

14
คุณช่วยชีวิตฉันไว้ จะปลอดภัยหรือไม่ที่จะทดแทนอย่างสมบูรณ์? ฉันหมายถึงทำwindow.Event= CustomEventในบรรทัดสุดท้าย
tfrascaroli

7
ใน IE11 ดูเหมือนว่าจะปลอดภัยในการตั้ง window.Event = CustomEvent ใช่
Corey Alix

10
สำหรับใครที่สนใจมันเป็นไปได้ที่จะตรวจสอบว่าคุณอยู่ใน IE (สำหรับกรณีนี้) โดยการตรวจสอบ typeof (เหตุการณ์) ซึ่งเป็น 'ฟังก์ชั่น' สำหรับทุกคนยกเว้น IE ที่เป็น 'วัตถุ' จากนั้นคุณสามารถ polyfill ตัวสร้างเหตุการณ์ได้อย่างปลอดภัยโดยใช้วิธีการด้านบน
Euan Smith

ฉันแค่ตรวจสอบวิธีแก้ปัญหาที่คล้ายกันStorageEventและtypeof(StorageEvent)ไม่ทำงานใน MS Edge งานนี้: try { new StorageEvent(); } catch (e) { /* polyfill */ }.
kamituel

1
อาจไม่ปลอดภัยในการแทนที่หน้าต่าง CustomEvent ถ้าคุณใช้ไลบรารีของบุคคลที่สามซึ่งใช้ตัวสร้าง CustomEvent ที่กำหนดโดย IE
Sen Jacob

55

ฉันคิดว่าทางออกที่ดีที่สุดในการแก้ปัญหาของคุณและจัดการกับการสร้างกิจกรรมข้ามเบราว์เซอร์คือ:

function createNewEvent(eventName) {
    var event;
    if (typeof(Event) === 'function') {
        event = new Event(eventName);
    } else {
        event = document.createEvent('Event');
        event.initEvent(eventName, true, true);
    }
    return event;
}

3
มันได้ผล! ผมแค่คิดว่ามันควรดังนั้นฉันสามารถผ่านมันไปreturn event dispatchEvent()
Noumenon

initEventเก่าและเลิกใช้แล้วคุณจะต้องใช้วิธีการที่ทันสมัยอย่างน้อยที่สุดและในฐานะที่เป็นทางเลือกให้ใช้วิธีเลิกใช้
vsync

2
@vsync มันอาจจะเลิก แต่เอกสารที่คุณเชื่อมโยงกับพูดว่า "แทนที่จะใช้ก่อสร้างเหตุการณ์เฉพาะเช่นเหตุการณ์ ()" ซึ่งเป็นว่าสิ่งนี้จะพยายาม polyfill จึงมีไม่มีทางเลือกจริงๆ
reduckted

1
CustomEventอนุญาตให้ส่งผ่านข้อมูลที่กำหนดเองผ่านdetailตัวเลือกและEventไม่ ฉันผิดหรือเปล่า?
pttsky

1
CustomEvent ไม่รองรับ IE9, 10 หรือ 11 ตามประสบการณ์ของฉัน คำตอบที่ดีเพียงข้อเดียวดูเหมือนจะเป็นที่ยอมรับ
UndyingJellyfish

5

แพ็คเกจนี้ใช้เวทย์มนตร์:

https://www.npmjs.com/package/custom-event-polyfill

รวมแพ็คเกจและส่งเหตุการณ์ดังต่อไปนี้:

window.dispatchEvent(new window.CustomEvent('some-event'))

95 พึ่งพา?
ดาเมียนโรช

4
@DamienRoche เป็นไปได้ไหมที่คุณจะพลาด "ผู้ติดตาม" ในฐานะ "การพึ่งพา" เนื่องจากแพคเกจนั้นมีการขึ้นต่อกัน 0 รายการและ (ตามเวลาของการเขียน) 102 ผู้อ้างอิง (เช่นแพคเกจที่ขึ้นอยู่กับมัน) 102 แพ็คเกจที่ขึ้นอยู่กับการใช้อาจเป็น 95 ครั้งในเดือนกรกฎาคม
ไข้หวัดใหญ่

2
ฉันเลือดดีก็ทำได้! : P
Damien Roche

3

หากคุณเพียงแค่พยายามส่งเหตุการณ์ง่ายๆเช่นเหตุการณ์สลับ HTML สิ่งนี้ใช้ได้ใน Internet Explorer 11 เช่นเดียวกับเบราว์เซอร์อื่น ๆ :

let toggle_event = null;
try {
    toggle_event = new Event("toggle");
}
catch (error) {
    toggle_event = document.createEvent("Event");
    let doesnt_bubble = false;
    let isnt_cancelable = false;
    toggle_event.initEvent("toggle", doesnt_bubble, isnt_cancelable);
}
// disclosure_control is a details element.
disclosure_control.dispatchEvent(toggle_event);

5
ไม่สามารถดูได้ว่าทำไมคุณกำลังมิกซ์es6 let(และไม่ใช้var) ด้วยโค้ดที่ควรรันบน IE เก่า .. มันอาจสร้างความสับสนให้กับผู้เริ่มต้นที่จะคัดลอกสิ่งนี้
vsync

1
@vsync ยักผมไม่ได้พูดถึงหมายเลขรุ่น เว็บไซต์ส่วนตัวของฉันตั้งเป้าหมายที่ IE11 เมื่อปีที่แล้วดังนั้นฉันจึงไม่เคยตรวจสอบการสนับสนุนในเวอร์ชั่นเก่า (ณ วันนี้ฉันให้บริการ HTML ธรรมดา IE11 โดยไม่มีสไตล์หรือสคริปต์ผู้คนจำเป็นต้องดำเนินการต่อ) ในกรณีใด ๆ Internet Explorer รุ่นเดียวที่ยังคงได้รับการสนับสนุนโดย Microsoft ณ วันที่ 2017 เมษายนเป็นรุ่นที่ 11 ดังนั้นจึงเป็นเรื่องเล็กน้อย จุดที่สงสัย ฉันไม่แนะนำให้ทุกคนใช้เบราว์เซอร์ที่ไม่รองรับโดยกำหนดเป้าหมาย เว็บอาจเป็นสถานที่ที่อันตราย
Patrick Dark

3
มันไม่เกี่ยวกับเรื่องนั้นเลยและไม่เกี่ยวกับการพยายามเปลี่ยนโลกหรืออะไรก็ตาม ตัวอย่างเช่นชื่อคำถามที่ถามเฉพาะIE 9ข้างต้นและอาจเป็นบุคคลที่ค้นหาคำตอบที่พบหัวข้อนี้กำลังพัฒนาแอพสำหรับระบบธนาคารแบบดั้งเดิมหรือระบบอื่น ๆ สำหรับลูกค้าธุรกิจที่ไม่มีการควบคุมคอมพิวเตอร์และ จำเป็นต้องทำงานกับ IE เก่า สิ่งนี้ไม่เกี่ยวข้องกับฝ่ายสนับสนุนของ Microsoft ..
vsync


2

custom-eventแพคเกจ NPM ทำงานสวยงามสำหรับผม

https://www.npmjs.com/package/custom-event

var CustomEvent = require('custom-event');

// add an appropriate event listener
target.addEventListener('cat', function(e) { process(e.detail) });

// create and dispatch the event
var event = new CustomEvent('cat', {
  detail: {
    hazcheeseburger: true
  }
});
target.dispatchEvent(event);

นี่เป็นคำตอบที่ดี แต่มีแพ็กเกจ NPM อื่นที่กล่าวถึงเป็นคำตอบแล้ว
mikemaccana

2
เกิดอะไรขึ้นกับการให้ตัวเลือกที่หลากหลายแก่ผู้ใช้
Liran H

แพคเกจทั่วไปเพิ่มเติมคือnpmjs.com/package/events-polyfill
Markus Jarderot

1

ฉันเองใช้ฟังก์ชั่น wrapper เพื่อจัดการกับเหตุการณ์ที่สร้างขึ้นด้วยตนเอง รหัสต่อไปนี้จะเพิ่มวิธีการคงที่ในทุกEventอินเทอร์เฟซ (ตัวแปรโกลบอลทั้งหมดที่ลงท้ายด้วยEventเป็นอินเทอร์เฟซของเหตุการณ์) และอนุญาตให้คุณเรียกใช้ฟังก์ชันเช่นelement.dispatchEvent(MouseEvent.create('click'));บน IE9 +

(function eventCreatorWrapper(eventClassNames){
    eventClassNames.forEach(function(eventClassName){
        window[eventClassName].createEvent = function(type,bubbles,cancelable){
            var evt
            try{
                evt = new window[eventClassName](type,{
                    bubbles: bubbles,
                    cancelable: cancelable
                });
            } catch (e){
                evt = document.createEvent(eventClassName);
                evt.initEvent(type,bubbles,cancelable);
            } finally {
                return evt;
            }
        }
    });
}(function(root){
    return Object.getOwnPropertyNames(root).filter(function(propertyName){
        return /Event$/.test(propertyName)
    });
}(window)));

แก้ไข:ฟังก์ชั่นการค้นหาEventอินเตอร์เฟซทั้งหมดยังสามารถถูกแทนที่ด้วยอาร์เรย์เพื่อเปลี่ยนเฉพาะกิจกรรมที่คุณต้องการ ( ['Event', 'MouseEvent', 'KeyboardEvent', 'UIEvent' /*, etc... */])

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