OnsenUIをIE11で動かしたい
-
OnsenUIを使用したCordovaアプリをInternet Explorer 11(以下IE11)で実行した場合、ブラウザは起動するのですが真っ白い画面のままHTML画面が表示されません。
IE11の開発者ツールからJavaScriptコンソールを確認してもエラーなどは表示されていませんでした。
IE11で起動する際には以下のコマンドで実行しています。
cordova run browser
※デフォルトブラウザをIE11に変更後にコマンドを実行。念のためWindowsアプリとして実行させたところ、以下のエラーが表示されました。
SCRIPT16386: ハンドルされない例外 下記ソースコードの行 9519、列 5 で発生しました。ms-appx://io.onsen.sampleapp/www/lib/onsen/js/onsenui.js 0x80004002 - JavaScript 実行時エラー: インターフェイスがサポートされていません onsenui.js (9519,5)
Windowsアプリとして実行させる際には以下のコマンドを実行しています
cordova run windows
※config.xmlには「<preference name=“windows-target-version” value=“8.1” />」を指定。- プロジェクト環境
OnsenUI 2.8.2
cordova-cli 7.0.0
cordova-browser 5.0.1
cordova-windows 5.0.0 - 実行環境
Windows 10(64bit)
Internet Explorer 11 11.64.16299.0
問題再現を行った最小限のソースは以下になります。
- index.html (www/index.html)
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8" /> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta http-equiv="content-language" content="ja"> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" /> <!-- Poliyfill --> <script src="lib/promise-polyfill/promise.js"></script> <script src="scripts/polyfill_CustomEvent.js"></script> <script src="scripts/polyfill_remove.js"></script> <!-- Unused Poliyfill? --> <!--<script src="scripts/polyfill_classList.js"></script>--> <!--<script src="scripts/polyfill_Set_Map_WeakMap.js"></script>--> <!--<script src="scripts/polyfill_MutationObserver.js"></script>--> <script src="scripts/platformOverrides.js"></script> <script src="lib/onsen/js/onsenui.js"></script> <link rel="stylesheet" href="lib/onsen/css/onsenui.css" /> <link rel="stylesheet" href="lib/onsen/css/onsen-css-components.css" /> </head> <body> <script src="cordova.js"></script> <script src="scripts/index.js"></script> <ons-navigator id="myNavigator"></ons-navigator> </body> </html>
- index.js (www/scripts/index.js)
(function () { "use strict"; document.addEventListener("deviceready", function () { ons.ready(onOnsenUIReady); }); window.onerror = function (msg, url, line, col, error) { alert("Error 1:" + msg); return false; }; window.addEventListener("error", function (e) { alert("Error 2:" + e.error.message); }); })(); function onOnsenUIReady(event) { document.addEventListener("init", onInit); var myNavigator = document.getElementById("myNavigator"); myNavigator.pushPage("html/page1.html"); } function onInit(event) { if (event.target.id === "Page1") { console.debug("Page1 Init!"); alert("Page1 Init!"); } }
- page1.html (www/html/page1.html)
<ons-page id="Page1"> This is Page1. </ons-page>
- Polyfill
・Promise
https://github.com/taylorhakes/promise-polyfill
・CustomEvent
https://developer.mozilla.org/ja/docs/Web/API/CustomEvent/CustomEvent
・remove
https://developer.mozilla.org/ja/docs/Web/API/ChildNode/remove
今回のアプリはIE11で動作させる必要があるため、Polyfillを導入する必要があります。
OnsenUIをIE11で使用するために導入すべきPolyfillが以下に記載されています。
https://ja.onsen.io/v2/guide/faq.html#furuiburauznosapto
今回追加したPolyfillは外部から導入した物のため、OnsenUIに適合しているのか不安があります。
OnsenUIで動作確認の取れているPolyfill実装があったら教えてください。
また、記載されているPolyfill追加以外に、エラー対応などのために必要な処理があるのでしょうか?- English digest
An error occurred when IE 11 executed it.
I would like to know Polyfill which was confirmed to work on OnsenUI.
Also, I would like to know other measures if necessary.
- プロジェクト環境
-
@imanishik
ご質問ありがとうございます。OnsenUIで動作確認の取れているPolyfill実装があったら教えてください。
IE11 は Onsen UI のサポート対象ブラウザに含まれていないため、現時点では
Polyfill 実装の動作確認も行っておりません。
ご理解の程よろしくお願いいたします。
-
@imanishik said:
また、記載されているPolyfill追加以外に、エラー対応などのために必要な処理があるのでしょうか?
polyfill を追加して動作しない場合、何らかのエラー対応処理を記述する必要があると思われますが、
処理の詳細については Onsen UI チームとしては現状把握できておりません。
ご期待に添えず申し訳ありませんが、よろしくお願いいたします。
-
動作確認が取れているPolyfillは無いと言う事で了解しました。
いろいろ試したところ、Cordova+OnsenUI+IE11環境で、Cordova、OnsenUIの初期化でエラーが発生せずアプリ起動する事が出来たため後継のために記載しておきます。具体的には以下の二つのPolyfillを導入しました。
・webcomponentsjs
https://github.com/webcomponents/webcomponentsjs
・remove
https://developer.mozilla.org/ja/docs/Web/API/ChildNode/remove簡単な動作確認のソースは以下となります。
- index.html (www/index.html) (使用するPolyfillを変更)
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8" /> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta http-equiv="content-language" content="ja"> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" /> <!-- Poliyfill --> <script src="lib/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script> <script src="scripts/polyfill_remove.js"></script> <!-- JS dependencies (order matters!) --> <script src="scripts/platformOverrides.js"></script> <script src="lib/onsen/js/onsenui.js"></script> <!-- CSS dependencies --> <link rel="stylesheet" href="lib/onsen/css/onsenui.css" /> <link rel="stylesheet" href="lib/onsen/css/onsen-css-components.css" /> </head> <body> <script src="cordova.js"></script> <script src="scripts/index.js"></script> <ons-navigator id="myNavigator"></ons-navigator> </body> </html>
- index.js (www/scripts/index.js) (Promiseの実験処理を追加)
(function () { "use strict"; document.addEventListener("deviceready", function () { ons.ready(onOnsenUIReady); }); window.onerror = function (msg, url, line, col, error) { //alert("Error 1:" + msg); return false; }; window.addEventListener("error", function (e) { //alert("Error 2:" + e.error.message); }); })(); function onOnsenUIReady(event) { document.addEventListener("init", onInit); var myNavigator = document.getElementById("myNavigator"); myNavigator.pushPage("html/page1.html"); } function onInit(event) { if (event.target.id === "Page1") { console.debug("Page1 Init!"); // Promise Test testPromise().then(function (message) { console.debug("testPromise then:" + message); }).catch(function (err) { console.debug("testPromise catch:" + err); }); } } function testPromise() { return new Promise(function (resolve, reject) { setTimeout(function () { console.debug("testPromise!"); resolve("ABC"); }, 1000); }); }
- page1.html (www/html/page1.html)
<ons-page id="Page1"> This is Page1. </ons-page>
引き続き、もう少しES6的な処理で動作するか検証してみたいと思います。
-
引き続き確認したところ、前出のPolyfillでは不十分のようです。
画面遷移(pushPage、popPage)等が正常に動作しませんでした。対策として、以下のPolyfillを登録する事で動作する事が確認できました。
・OnsenUI 2.3.0で削除されたPolyfill(=2.2.6まで登録されていたPolyfill)
・webcomponentsjs
https://github.com/webcomponents/webcomponentsjsしかし上記Polyfillを導入しても、ダイアログ(ons.notification.alert)や、トースト(ons.notification.toast)を閉じる際に以下のエラーが表示され、以降のダイアログ表示などが行えなくなります。
Unhandled promise rejection TypeError: 未定義または NULL 参照のプロパティ 'destroy' は取得できません
onsen.jsの以下の処理で、this._backButtonHandlerがnullとなっている事が原因のようです。
key: 'disconnectedCallback', value: function disconnectedCallback() { this._backButtonHandler.destroy();
そのため、OnsenUI側のonsen.jsに手を加え、this._backButtonHandlerのnullチェックを追加する事でダイアログ系が正常に動作する事が確認できました。
引き続き調査してみたいと思います。
-
引き続きIE11にて確認したところ、ons-carouselやons-tabでの横スライドの遷移にて画面が正常に表示されない問題が発生しました。
スライドの1ページ目は表示されるのですが、スライドさせても2ページ目以降の項目が表示されません。
ons-carousel内に生成されるdivに、縦スライドのスタイル「ons-swiper-target–vertical」が追加されている事が原因となります。
横スライド設定にも関わらず、縦スライド向けスタイルシートが適用されているのは以下の箇所(onsenui.js(2.8.3)の15221行目)が原因となります。key: '_updateLayout', value: function _updateLayout() { this.target.classList.toggle('ons-swiper-target--vertical', this.isVertical());
IE11ではelement.classList.toggleの第二引数に対応していない事が原因のようです。
https://caniuse.com/#feat=classlist
そのため、上記処理のclassList.toggleにて第二引数が無視されons-swiper-target–verticalクラスが追加されているようです。OnsenUI側のonsen.jsに以下のように手を加える事で対策する事が出来ました。
key: '_updateLayout', value: function _updateLayout() { //this.target.classList.toggle('ons-swiper-target--vertical', this.isVertical());// Comment out if (this.isVertical()) { this.target.classList.add("ons-swiper-target--vertical"); } else { this.target.classList.remove("ons-swiper-target--vertical"); }
もし可能であれば上述の「this._backButtonHandlerのnullチェック」と合わせて「classList.toggleのadd/remove化」を次回のOnsenUIリリースに混ぜていただけると幸いです。
-
引き続き確認したところ、IE11にて以下の問題が発生しました。
ons-rangeを表示し操作したところ、スライダーボタンの移動がレンジの線に正常に反映されませんでした。
確認時のソースはリファレンスの物をそのまま使用しています。
原因を調べたところ、OnsenUI側で操作による画面更新(RangeElementの_update)が呼び出されていませんでした。
具体的には以下のイベント登録によるユーザー側の操作イベント(input)が発生しないようです。var RangeElement = function (_BaseInputElement) { key: 'connectedCallback', value: function connectedCallback() { this.addEventListener('input', this._boundOnInput);// not working on IE11
この問題はIE11でのみ発生し、他のモダンブラウザ(ChromeやEdge)では発生しません。
対策として動作環境がIE11の場合は、changeイベントをリスナー登録する必要があるようです。var RangeElement = function (_BaseInputElement) { key: 'connectedCallback', value: function connectedCallback() { this.addEventListener('input', this._boundOnInput); // for IE11 if (ons.platform.isIE()){ this.addEventListener('change', this._boundOnInput); }
これにより、レンジのスライダー操作のイベントを取得する事が出来、現在のスライダーの位置に正常にレンジの線が表示されました。