Internet Explorer 9、10、11のイベントコンストラクターが機能しない


129

私はイベントを作成しているので、DOM Eventコンストラクターを使用します。

new Event('change');

これは最新のブラウザでは問題なく機能しますが、Internet Explorer 9、10、11では次のエラーで失敗します。

Object doesn't support this action

Internet Explorerを修正するにはどうすればよいですか(理想的にはポリフィルを使用)。できない場合、使用できる回避策はありますか?


55
「どうすればInternet Explorerを修正できますか?」xD
contactmatt 2017

回答:


176

MDNには、CustomEventコンストラクター用のIEポリフィルがあります。IEにCustomEventを追加し、代わりにそれを使用すると機能します。

(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 2016年

10
興味のある人にとっては、IEが「オブジェクト」であるIEを除くすべてに対して「関数」であるtypeof(Event)をチェックすることで、IEにいることを検出できる(この場合)ようです。その後、上記のアプローチを使用して、Eventコンストラクタを安全にポリフィルできます。
Euan Smith

私はちょうどのために同様の回避策を調査していますStorageEventし、typeof(StorageEvent)MSエッジでは動作しません。これは機能しますtry { new StorageEvent(); } catch (e) { /* polyfill */ }
kamituel

1
IEで定義されたCustomEventコンストラクターを使用するサードパーティライブラリを使用している場合、window.CustomEventを置き換えるのは安全ではない可能性があります。
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 2017

initEventは古く、非推奨です。少なくとも最新の方法を使用し、フォールバックとして非推奨の方法を使用する必要があります。
vsync

2
@vsyncそれは非推奨、しかし、あなたが言うにリンクドキュメントかもしれない「の代わりにイベント(のように、特定のイベントのコンストラクタを使用)」であり、これはまさにこれはポリフィルしようとしているので、選択の余地が本当にありません何。
17

1
CustomEventdetailオプションを介してカスタムデータを渡すことができますが、渡しEventません。私が間違っている?
pttsky

1
CustomEventは、IE 9、10、11ではサポートされていません。唯一の良い答えは受け入れられるようです。
UndyingJellyfish

5

このパッケージは魔法を行います:

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

パッケージを含めて、次のようにイベントをディスパッチします。

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

95の依存関係?
Damien Roche

4
@DamienRoche「Dependents」を「Dependencies」として読み間違えたのではないですか?パッケージには実際には依存関係がなく、(執筆時点では)102個の依存関係がある(つまり、パッケージに依存するパッケージ)。その102の依存パッケージはおそらく7月に95でした。
インフルエンザ

2
流血よかった!:P
ダミアンロシュ

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
なぜ古いIEで実行するはずのコードと混在しているes6 let(そしてを使用していないvar
かがわかり

1
@vsyncは肩をすくめ、私がやったバージョン番号に言及します。私の個人的なWebサイトは、昨年IE11のみを対象としていたため、古いバージョンのサポートを確認することはありませんでした。(今日、私はスタイルシートやスクリプトなしでIE11プレーンHTMLを提供しています。人々は先に進む必要があります。)いずれにしても、2017年4月の時点でMicrosoftによってサポートされているInternet Explorerの唯一のバージョンはバージョン11であるため、少々問題点。サポートされていないブラウザーをターゲットにして使用することはだれにも勧めません。Webは危険な場所になる可能性があります。
Patrick Dark

3
それはまったくそのことではなく、世界や何かを変えようとすることでもありません。たとえば、質問のタイトルが具体的にIE 9以上を求めている場合、そしておそらくこのスレッドを見つけた回答を求めている人が、レガシーバンキングシステム用のアプリや、コンピューターを制御できず、古いIEを使用する義務があります。これは...マイクロソフトのサポートとは何の関係もありません
VSYNC

3

これと他のものをあなたのためにパッチすることができるポリフィルサービスがあります

https://polyfill.io/v3/url-builder/

 <script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js"></script>

2

custom-eventNPMパッケージには、私のために働い美しく

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
マルクスJarderot

1

私は個人的にラッパー関数を使用して、手動で作成されたイベントを処理します。次のコードは、すべてのEventインターフェースに静的メソッドを追加し(末尾がすべてのグローバル変数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.