forEach Function Not Working in Recent Microsoft Browsers
Web アプリケーションで製品選択用のスクリプトを作成しようとして、開発者が次のような問題に遭遇しました。 Internet Explorer 11 および Microsoft Edge でのエラー。エラー メッセージは、forEach 関数が IE9 以降のバージョンで利用可能であると報告されているにもかかわらず、サポートされていないことを示していました。
問題の調査
forEach メソッドは通常、配列要素を反復処理し、各要素に関数を適用するために使用されます。この場合、開発者は製品の構成から色のオプションを選択する方法を利用しました。ただし、調査の結果、次のコード スニペット:
var color_btns = document.querySelectorAll('#color > p'); color_btns.forEach(function(color) { color.onclick = function () { color_btns.forEach(function(element) { if (element.classList.contains('selected')) { element.classList.remove('selected'); } }); color.classList.add('selected'); document.querySelector('#f_color').value = color.dataset.id; }; });
が Internet Explorer および Microsoft Edge で期待どおりに機能せず、forEach 関数が NodeList のプロパティではないことを示すエラーがスローされることが判明しました。 querySelectorAll.
問題の理由
さらなる調査の結果、querySelectorAll および類似のメソッドによって返されるオブジェクトのタイプである NodeList と HTMLCollection が次のとおりであることが判明しました。本当の配列ではなく、反復可能です。 JavaScript では、イテラブルとは、for-of ループ、スプレッド演算子、または代入の構造化を使用して反復できるオブジェクトです。
NodeList オブジェクトは最近 forEach メソッドのサポートを取得しましたが、HTMLCollection オブジェクトはサポートされておらず、サポートされることも期待されていませんそれをサポートするために。これは、forEach メソッドを HTMLCollection に追加すると既存のコードが壊れる可能性があるため、下位互換性の問題によるものです。
Polyfilling forEach
この問題を解決するには、次のことをお勧めします。 NodeList オブジェクトの forEach メソッドをポリフィルします。ポリフィルには、ネイティブにサポートされていないメソッドをオブジェクトに追加することが含まれます。次のコード スニペットは、NodeList の forEach をポリフィルできます:
if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) { NodeList.prototype.forEach = Array.prototype.forEach; }
上記のコードに示すように、enumerable、configurable、writable がすべて true である必要があり、値プロパティであるため、直接割り当てが可能です。
ポリフィルの反復性
さらに、NodeList オブジェクトを反復可能にして、for-of ループとスプレッド演算子を使用した反復をサポートすることもできます。これは、次のポリフィルを使用して実現できます。
if (typeof Symbol !== "undefined" && Symbol.iterator && typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype[Symbol.iterator]) { Object.defineProperty(NodeList.prototype, Symbol.iterator, { value: Array.prototype[Symbol.iterator], writable: true, configurable: true }); }
ポリフィルを使用した例
これらのポリフィルを組み込むことで、サポートされているすべての環境でシームレスに実行されるように元のコードを変更できます。ブラウザ:
// Polyfilling forEach for NodeList if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) { NodeList.prototype.forEach = Array.prototype.forEach; } // Polyfilling iterability for NodeList if (typeof Symbol !== "undefined" && Symbol.iterator && typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype[Symbol.iterator]) { Object.defineProperty(NodeList.prototype, Symbol.iterator, { value: Array.prototype[Symbol.iterator], writable: true, configurable: true }); } var color_btns = document.querySelectorAll('#color > p'); color_btns.forEach(function(color) { color.onclick = function () { color_btns.forEach(function(element) { if (element.classList.contains('selected')) { element.classList.remove('selected'); } }); color.classList.add('selected'); document.querySelector('#f_color').value = color.dataset.id; }; });
この更新されたコード スニペットは、Internet Explorer や Microsoft Edge を含むすべてのブラウザで意図したとおりに機能するはずです。
以上がInternet Explorer および Microsoft Edge で forEach 関数が機能しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。