Internet Explorer 9, 10 ve 11 Olay oluşturucu çalışmıyor


129

Bir etkinlik oluşturuyorum, bu nedenle DOM Event yapıcısını kullanın:

new Event('change');

Bu, modern tarayıcılarda iyi çalışır, ancak Internet Explorer 9, 10 ve 11'de şu durumlarda başarısız olur:

Object doesn't support this action

Internet Explorer'ı (ideal olarak bir çoklu dolgu aracılığıyla) nasıl düzeltebilirim? Yapamıyorsam, kullanabileceğim bir çözüm var mı?


56
"Internet Explorer'ı nasıl düzeltebilirim?" xD
contactmatt

Yanıtlar:


176

MDN'de CustomEvent kurucusu için bir IE çoklu dolgusu var . IE'ye CustomEvent eklemek ve onun yerine onu kullanmak işe yarar.

(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
Siz bayım hayatımı kurtardınız. Tam bir ikame yapmak güvenli olur mu? Demek istediğim, window.Event= CustomEventson satırda yapmak.
tfrascaroli

7
IE11'de window.Event = CustomEvent, yes.Event ayarlamak güvenli görünüyor.
Corey Alix

10
İlgilenen herhangi biri için, IE'de olduğunuzu (bu durumda), "nesne" olduğu IE dışındaki herkes için "function" olan typeof (Event) 'i kontrol ederek tespit etmek mümkün görünüyor. Ardından, yukarıdaki yaklaşımı kullanarak Event yapıcısını güvenle çoklu doldurabilirsiniz.
Euan Smith

MS Edge için benzer bir geçici çözümü araştırıyorum StorageEventve typeof(StorageEvent)çalışmıyor. Bu çalışır: try { new StorageEvent(); } catch (e) { /* polyfill */ }.
kamituel

1
IE tanımlı CustomEvent yapıcısını kullanan üçüncü taraf kitaplıkları kullanıyorsanız, window.CustomEvent'i değiştirmek güvenli olmayabilir.
Sen Jacob

55

Sorununuzu çözmek ve tarayıcılar arası etkinlik oluşturmayla başa çıkmak için en iyi çözümün şudur:

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
İşe yarıyor! Sadece return eventgeçmesi gerektiğini düşünüyorum, böylece onu aktarabilirim dispatchEvent().
Noumenon

initEventeski ve kullanımdan kaldırılmışsa , en azından modern yöntemi kullanmanız ve geri dönüş olarak, kullanımdan kaldırılmış yolu kullanmanız gerekir.
vsync

2
@vsync Kullanımdan kaldırılmış olabilir, ancak bağladığınız dokümanlar "Bunun yerine, Event () gibi belirli olay oluşturucularını kullanın" diyor ki bu tam olarak çoklu doldurmaya çalışıyor, yani gerçekten başka seçenek yok.
42'de reducked

1
CustomEventözel verilerin detailseçenek üzerinden aktarılmasına izin verir ve Eventvermez. Yanlış mıyım?
pttsky

1
CustomEvent, kendi deneyimlerime göre IE9, 10 veya 11 için desteklenmiyor. Tek iyi cevap kabul edilmiş gibi görünüyor.
UndyingJellyfish

5

Bu paket sihir yapar:

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

Paketi ekleyin ve olayı aşağıdaki gibi gönderin:

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

95 bağımlılık mı?
Damien Roche

4
@DamienRoche "Bağımlılar" ı "Bağımlılıklar" olarak yanlış okuyabilir misiniz? Çünkü paket aslında 0 bağımlılığa ve (yazarken) 102 bağımlıya (yani, ona bağlı paketlere) sahiptir. Bu 102 bağımlı paket muhtemelen temmuz ayında 95'ti.
grip

2
Çok iyi yaptım! : P
Damien Roche

3

HTML geçiş olayı gibi basit bir olayı göndermeye çalışıyorsanız, bu hem Internet Explorer 11'de hem de diğer tarayıcılarda çalışır:

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
eski IE'de çalıştırılması gereken bir kodla neden karıştırdığınızı es6 let(ve kullanmadığınızı var) anlayamıyorum .. bunu kopyalayıp yapıştıracak olan yeni başlayanların kafasını karıştırabilir
vsync

1
@vsync silkip ben yaptım sürüm numarasını söz. Kişisel web sitem geçen yıl yalnızca IE11'i hedefliyordu, bu yüzden eski sürümlerdeki desteği kontrol etmek hiç aklıma gelmedi. (Bugün itibariyle, stil sayfaları veya komut dosyaları olmadan IE11 düz HTML sunuyorum. İnsanların devam etmesi gerekiyor.) Her halükarda, Nisan 2017 itibarıyla Microsoft tarafından desteklenen tek Internet Explorer sürümü, sürüm 11'dir, bu nedenle biraz tartışma noktası. Hiç kimseyi desteklenmeyen bir tarayıcıyı hedefleyerek kullanmaya teşvik etmem. Web tehlikeli bir yer olabilir.
Patrick Dark

3
bununla ilgili değil, dünyayı veya başka bir şeyi değiştirmeye çalışmakla da ilgili değil. Örneğin, sorunun başlığı özellikle soruluyor IE 9ve yukarıda ve belki de bu konuyu bulan bir cevap arayan bir kişi, eski bankacılık sistemi için bir uygulama veya bilgisayarları üzerinde kontrolü olmayan ve şu anda daha yüksek olan ticari müşteriler için başka bir sistem geliştiriyor olabilir. eski IE ile çalışmak zorunda. bunun Microsoft Destek ile ilgisi yok ..
vsync


2

custom-eventnpm paket benim için güzel çalıştı

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

Bu iyi bir cevap, ancak zaten yanıt olarak bahsedilen başka bir UÖM paketi var.
mikemaccana

2
Kullanıcılara çeşitli seçenekler sunmanın nesi yanlış?
Liran H


1

Ben şahsen elle oluşturulmuş olayları işlemek için bir sarmalayıcı işlevi kullanıyorum. Aşağıdaki kod, tüm Eventarabirimlere statik bir yöntem ekler (ile biten tüm global değişkenler Eventbir Etkinlik arabirimidir) ve element.dispatchEvent(MouseEvent.create('click'));IE9 + 'da olduğu gibi işlevleri çağırmanıza izin verir .

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

DÜZENLEME: Tüm Eventarabirimleri bulma işlevi, yalnızca ihtiyacınız olan Etkinlik arabirimlerini değiştirmek için bir dizi ile değiştirilebilir ( ['Event', 'MouseEvent', 'KeyboardEvent', 'UIEvent' /*, etc... */]).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.