もう怖くないInternet Explorer対応
IE!それはエンジニアを恐怖に陥れるブラウザ
IE!それは実装を先んじすぎたがために滅びることとなったブラウザ
奢れるものも久しからず、ただ風の前の塵に等しい…
我々はこの滅びゆくブラウザに対しても対応を行わなければならないことが時折発生します。
そのため、ここに基本的なInternet Explorerへの対応方法をまとめ、しるすことにしました。
※この記事はIE11への対応を想定していますが、Androidブラウザのような他のブラウザやIE11以前のものに対してもこの考え方は役に立つ部分があるでしょう。
BtoCで一般の人が使うなら、仕方がありませんが、IE11以外のIEに対応してくれと言ってくるような、セキュリティ意識の低い会社とは取引しないようにしましょう。
IE対応って何するの?
IE対応とは、もちろんIEでWEBアプリケーションを動くようにすることなのですが
実際には、何をしたらIE対応をしたことになるのか、考えてみましょう。
そうすると、IE対応では以下の2つのことをすればよいことがわかります。
- IEにはない機能を追加すること。
- IEと他のブラウザで機能に差異がある部分を吸収する。
これを突き詰めていけばIE対応はもう怖くない!
IEと他のブラウザで機能に差異がある
デザイン崩れを調整する
IEで表示すると、デザインが崩れてしまうことがあります。
実はこれが一番面倒で、対応もまちまちになってしまいます。
主に、flexboxを使おうとしたときにデザイン崩れが起こりがちです。
IE対応の必要なアプリケーションを作成する際にflexboxを使用する場合は、早い段階でIEでデザインを確認するようにしたほうがよいでしょう。
User-Agentによって、処理を変える
特にプレフィクスつきの機能に多いのですが、Chromeなどのモダンなブラウザと挙動が違うものがあります。
この場合、User-Agentを見ることで、処理を変えるのが妥当でしょう。
もしも、現存の機能だけで、再現するのが難しい場合(暗号回りで使いたいアルゴリズムがないなど)はポリフィルを探してみるのもよいかもしれません。
セキュリティ設定の罠
IEでは、セキュリティ設定を変えないと使用できない機能があります。
これを見逃すと、エラーが出ずに黙って処理が終わることもあるので、使う機能がセキュリティ設定によって、制限されていないか?はしっかり確認しましょう。場合によっては、IEのためにユーザマニュアルを書き換えないといけない場合もあるかもしれません。
ちなみに私はpostMessageを使用していて、ローカル開発環境は同ドメイン、共通開発環境は違うドメイン同士で通信させていたところ
共通開発環境のみで、機能が動作せずそれで半日ほど溶かしたました・・・
IEにはない機能を追加する
IEは古いブラウザです。そのため、最新のブラウザには標準でついていても、IEにない機能がたくさんあります。
それらを追加することから始めましょう。
ポリフィルを使う
ポリフィルとは、JavaScriptで使えない関数やオブジェクトをJavaScript自体で実装することによって、他のブラウザと同様に使用できるようにする手法です。
有名どころだと、Babel-polyfillやPolyfill.ioなどがあります。
ただし、最新の機能だと、上記のライブラリにまだ追加されていない関数やオブジェクトがある場合があります。
その場合、これらの既に出来上がっているポリフィルを使うほかに自分で実装する方法もあります。
大体以下のような実装になることが多いです。
// hogehogeという関数がObjectにない場合
if (Object.prototype.hogehoge === undefined) {
Object.prototype.hogehoge = function () {
/**
* 実際の処理
*/
}
}
// Fugaというオブジェクトが存在しない場合
if (window.Futa === undefined) {
Fuga = function () {};
Fuga.prototype.toString = function () {
return "[Object Fuga]"
}
/**
* 他の機能
*/
}
自分で実装することになった場合、MDNで情報をしっかり読み仕様を把握したり
Chromiumのソース上に(Chromeにその機能があるなら)実装があるはずなので、探してどんな処理を行っているのか見てみるのがよいでしょう。
トランスパイルする
トランスパイルはIEで使えないJavaScriptの構文を使える形に変換する手法です。(他の使われ方もしますが)
IEのJavaScriptでは最新の構文(スプレッド構文やasync await)は使用できないうえに、パーシングの時点でエラーが出てしまうので
別の記法に置き換えなければならないのです。
(スプレッド構文であれば、Object.assign async await であれば、単純なコールバックなど)
よく使用されるのは、Babel-polyfillです。
代替の実装を行う
WebSQLや、新しいCSSプロパティなどのIEでは使用できない機能が元のアプリケーションで使われていた場合、代替の実装を行うことを考えましょう。例えばWebSQLであれば、localStorageなどのWebStorageを使用することができますし、CSSであれば、古いプロパティの組み合わせで新しいプロパティをできるだけ再現することで対応ができます。
そもそも、これIEじゃ不可能なのでは?
ここでは、例としてNotification APIに関して考えてみます。
Notification APIはブラウザがOSに対して通知を送るための機能です。ところが、IEではこの機能は実装されていませんし、ブラウザ上のJavaScriptだけではこれを再現することは不可能でしょう。
こういったときは、IEで対応することをあきらめるか、どうしても必ず必要なんだ!という場合は、別のクライアントアプリを作成し、通知を受け取らせるしかありません。
設計段階で、これを考慮していないと致命傷になります。
使用しそうな機能が本当にIEに存在しているかは、対応することが決まっているのであれば、必ず確認しましょう。