IEのために｜IE判定とバベルとポリフィル

IE嫌いでも、対応しないとクライアントは納得しなかったりする。
HTMLファイル内に数行をコピペするだけで、IE対応するために...のメモ

# STEP1） java script を Babel で IE対応に変換しておく
IEだとアロー関数とか使えないから
[Babel](https://babeljs.io/repl)で変換しておく

# STEP2） HTMLファイル内に記述
`</head>`の直前とかに下記のコードをコピペしておく

```html:html
<head>
<!-- 〜省略〜 -->
    <!-- IE対策 -->
    <script type="text/javascript">
      //prettier-ignore
      function addScript(path) {var script = document.createElement("script");script.type = "text/javascript";script.src = path;document.getElementsByTagName("head")[0].appendChild(script);}
      var userAgent = window.navigator.userAgent.toLowerCase();
      if (userAgent.indexOf("msie") !== -1 || userAgent.indexOf("trident") !== -1) {
        addScript("https://polyfill.io/v3/polyfill.min.js");
        addScript("https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js");
        addScript("https://cdnjs.cloudflare.com/ajax/libs/picturefill/3.0.3/picturefill.min.js");
      }
    </script>
    <!-- END IE対策 -->
</head>
```

ユーザーエージェントがIEのときに、スクリプトを`<head>`内に追加する。
IEのときは動作が重くなるけど、まぁ...しかたないさ。IEだもん

**IE**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/bb1cf5e3-c1eb-522e-17fe-2212b2e4bc9b.png)

↑ IEのときは`polyfill.io`などの外部スクリプトの読み込みが追加されている

**Chrome**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/ce1f7344-a93a-e887-c776-6be1fe390524.png)

↑　IEじゃないブラウザ（上記はChrome）なら外部スクリプトの読み込みが追加されていない


# 何をもって IE と判別するか
コメントで @htsign さんから「UA での判断は絶対ではないので…。」とアドバイスいただきました。調べてみるとなるほどです。

IE を判別する方法として２択あります。

## ユーザーエージェントでの判定
```javascript:javascript
if (userAgent.indexOf("msie") !== -1 || userAgent.indexOf("trident") !== -1)
```

## IE の機能で判別する （オススメ）
```javascript:javascript
if (document.documentMode && document.uniqueID) 
```

`document.documentMode` も `document.uniqueID` も IEの持つ特有の機能です。言い換えると「機能が存在する＝IE」ということのようです。こっちの方がパット見もスッキリですね

【参考サイト】
document.documentMode：[推奨されていないドキュメント モードと Internet Explorer 11](https://docs.microsoft.com/ja-jp/internet-explorer/ie11-deploy-guide/deprecated-document-modes)
document.uniqueID：[要素固有の ID を取得する](https://amachang.hatenablog.com/entry/20080602/1212386785)
[ユーザーエージェントに依存しない、JavaScriptでのブラウザハックまとめ](https://qiita.com/sawadays0118/items/325022cb987412d95a4b)


# よって最終的に...
```html:html
<head>
<!-- 〜省略〜 -->
    <!-- IE対策 -->
    <script type="text/javascript">
      //prettier-ignore
      function addScript(path) {var script = document.createElement("script");script.type = "text/javascript";script.src = path;document.getElementsByTagName("head")[0].appendChild(script);}
      if (document.documentMode && document.uniqueID) {
        addScript("https://polyfill.io/v3/polyfill.min.js");
        addScript("https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js");
        addScript("https://cdnjs.cloudflare.com/ajax/libs/picturefill/3.0.3/picturefill.min.js");
      }
    </script>
    <!-- END IE対策 -->
</head>
```

**IE**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/130ff87c-c44a-b4e9-95f3-c3c730e51c7f.png)

↑ `if (document.documentMode && document.uniqueID)` で判定して、scriptが追加されている様子

これでいきます。


# 他の記載方法
```html:html
<script type="text/javascript">
  document.documentMode && document.uniqueID && document.write('<script src="https://polyfill.io/v3/polyfill.min.js"><\/script>');
  document.documentMode && document.uniqueID && document.write('<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"><\/script>');
  document.documentMode && document.uniqueID && document.write('<script src="https://cdnjs.cloudflare.com/ajax/libs/picturefill/3.0.3/picturefill.min.js"><\/script>');
</script>
```

こんな方法もあるんですね！
こっちの方が`addScript()`みたいなfunctionを書かなくていいので楽ですね！

なお`document.documentMode && window.MSInputMethodContext && document.uniqueID`ってするとIE11に限定できるようです。

ちなみ、こんな感じになります（`</body>`タグの直前に追加されます）↓

![20220428.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/5f03472c-5462-fcdb-5efb-50df3ccd87ae.png)


【参考サイト】
[返せ、工数！コーダー泣かせの☓☓☓☓――IE11対応まとめ](https://ponsyon.com/archives/323)
[【javascrip】Internet Explorerを判定する方法](https://twotone.me/web/6025/)
[JavaScriptの「&&」「||」について盛大に勘違いをしていた件](https://qiita.com/Imamotty/items/bc659569239379dded55)
[AND演算子（&&）](https://jsprimer.net/basic/operator/#and-operator)
[MSInputMethodContext object](https://docs.microsoft.com/en-us/previous-versions/dn433247(v=vs.85))