IE11から削除されたdocument.createStyleSheetによる不具合例

2014年11月現在、Facebook側が報告受けてなのかは定かではありませんが、IE11におけるバグの再現性に気づき、Facebook SDKのスクリプトはIE11以上ではフォールバックコードが影響しないように無事修正されました。回避策をとる必要ももうありませんので、一時的に適用されていた方は削除するなりしてください。

Internet Explorerは、Version 4からドキュメントのスタイルシートを作成するdocument.createStyleSheet()という関数を独自に実装しました。しかし、document.createStyleSheet()関数がInternet Explorer 11(2013年10月18日リリース、2013年11月7日よりWindows 7 / Windows Server 2008 R2向けにも提供)より削除されています。この関数が削除されたことによって、Facebookなどのいいねボタンのフォールバックコードが偶発的に以降のCSS3のキーフレームアニメーション(@keyframes)や@-ms-viewportを無効にしてしまう不具合を起こす事例があることが判明しました。

本件の第一発見者は、Harri Halikka(harriha)さんで、その問題の回避策も提示して頂いております。何故、この問題が起こるのか、どのようにして回避できるのかについて、本文書にて筆者が理解できている範囲で解説いたします。解釈に間違いがあるなどございましたらご指導・ご鞭撻頂けましたら幸いです。そして一人でも多くのWeb制作者の皆様のお役にたてれば幸いです。

document.createStyleSheet()の使用ケースについて

当時のIE専用の関数であるdocument.createStyleSheet()なんて、そもそも誰も使わないよ!と思われるかもしれませんが、2014年2月18日現在のFacebookのいいねボタンなどをはじめとしたソーシャルプラグイン、またはJavaScriptライブラリ、JavaScriptフレームワークなどところどころでdocument.createStyleSheet()が使用されているようです。あくまでも利用者数が多くその影響範囲が大きい最たる例がFacebookのいいねボタンとなります。

document.createStyleSheet()が実行できないためにInternet Explorer 11で引き起こす不具合について

Facebookのいいねボタンをはじめとしたdocument.createStyleSheet()関数を含んでいるスクリプトの多くではdocument.createStyleSheet()が実行されなかった場合のフォールバックコードを用意していることがあります。その中で、Facebookのいいねボタンで用意されていたフォールバックコードでは偶発的にIE11においてバグを誘発させ、以降CSS3のキーフレームアニメーション(@keyframes)や@-ms-viewport指定が動作しなくなります。これは以下の条件が重なりあって発生するようです。

  1. これまでIE専用だったdocument.createStyleSheet()関数がIE11より削除された
  2. IE11にdocument.createStyleSheet()関数が存在しなくなったことで、各種スクリプト側でフォールバックとして用意されているコードが走ることになる
  3. フォールバック用のコードの中でIE11の既存のスタイルオブジェクト(キーフレームアニメーションや@-ms-viewport)を破壊する(cssTextプロパティに文字列としてCSSを追加している)コードが実行されている場合があり、IE11では既存のスタイルオブジェクト(キーフレームアニメーションや@-ms-viewport)を認識できなくなる不具合が発生する

もちろん、これはFacebookのいいねボタンであれば、Facebook側がdocument.createStyleSheet()を使用していないコードに修正すれば、解決される問題であります。しかしながら、2014年2月18日現在もコードは修正されていません。より多くの人が不具合を招いていると訴えかける必要があるのでしょう。

document.createStyleSheet()関連が招く不具合の回避策について

回避策の一例としては、Internet Explorer 11から削除されてしまったdocument.createStyleSheet()関数を再び認識できるようにしてあげる方法です。ここでは、@asamuzakjpさんより提示頂いた方法を紹介します。

♪NAI NAI NAI IEじゃない (c) シブがき隊 IE11はIEであってIEじゃない、IEとして扱おうとすると...♪そこが危NAIより
/*
*   Redefine document.createStyleSheet() in IE11
*   Free and unencumbered, released into the public domain.
*/
(function(d) {
    'use strict';
    d.documentMode === 11 && (d.createStyleSheet = function(s, i) {
        var o = d.createElement('style'), x;
        s && (x = new XMLHttpRequest(), x.onreadystatechange = function() {
            x.readyState === 4 && x.status === 200 && (o = d.createElement('link'), o.setAttribute('rel', 'stylesheet'), o.setAttribute('href', s));
        }, x.open('GET', s, false), x.send(null));
        i && (x = d.styleSheets, x[i]) ? (x = x[i].ownerNode, x.parentNode.insertBefore(o, x)) : d.querySelector('head').appendChild(o);
        return o.sheet;
    });
})(document);

上記のコードをFacebookのいいねボタンなどに代表されるdocument.createStyleSheet()を含むコードが実行される前に実行します。これでInternet Explorer 11が事前にdocument.createStyleSheet()関数を認識できるようになるので、フォールバックコードによって引き起こされるキーフレームアニメーション(@keyframes)や@-ms-viewportが認識できなくなるバグの誘発を回避できます。

もちろん原因は、IE11でdocument.createStyleSheet()関数が実行できないことによるフォールバックコードで偶発的に発生することが判明しているため、他にも回避策は考えられるかと思われます。

謝辞・参考情報

本件の第一発見者である Harri Halikka(harriha)さんに深く感謝申し上げます。また、筆者と一緒に本件の原因究明にご尽力頂いた@asamuzakjpさんに深く感謝申し上げます。原因が究明でき、おかげ様で筆者のサイトではIE11でも気持ちよくキーフレームアニメーションが動作するようになりました。多謝。

Updated / Published