IonicでつくるiOSアプリはすべてWKWebViewという機能で表示するように統一されました。
参考 : WKWebView for All: A new webview for Ionic
従来つかわれていたUIWebViewという機能で表示すると、JavaScriptの実行は遅いし、クラッシュ率高いし、iOS11ではバグがたくさん抱えているといった問題がありましたので歓迎すべきことなのですが、WordPressのWP API
などを用いてメディアアプリをつくっている方は一点だけ注意する点があります。外部リンク、もうちょっというとaタグのハンドリングです。
WKWebViewで躓いた10つのまとめなどで紹介されているように、a[taget="blank"]
は挙動しません。ちゃんと調査していないのですが、taget="blank"
のつかないa
タグだとアプリ自体が書き換えられてしまったはず。ですので、HTML上のaタグがクリックされた時、そのイベントをJavaScriptサイドでハンドリングしてあげる必要があります。
いろいろなやり方がありますが、私は以下のように実装しました。Timelineというページの実装です。
import { NavController } from 'ionic-angular';
import { Component } from '@angular/core';
import { InAppBrowser } from '@ionic-native/in-app-browser';
@Component({
templateUrl: 'timeline.html',
selector: 'timeline-page'
})
export class Timeline {
public linkListener: EventListenerObject | any;
constructor(
public nav: NavController,
public iab: InAppBrowser,
) {}
ionViewDidEnter(){
// イベント登録
document.querySelector("timeline-page").addEventListener('click',
this.linkListener = (e) => {
if(e.target.localName == 'a' && e.target.href){
e.preventDefault();
const browser = this.iab.create(e.target.href, '_system');
browser.show();
}
}, false);
}
ionViewDidLeave() {
// イベント削除
document.querySelector("timeline-page").removeEventListener('click',this.linkListener);
}
}
ionViewDidEnter()
はこのページが表示される時に自動的に実行されるメソッドです。ページが表示されたタイミングで、イベント登録を@Component
で登録したselector名<timeline-page>
に対して行っています。
その中の要素をクリックしたらイベントが実行されるようになっていて、クリックした要素がaタグだった場合は規定の処理をストップして(e.preventDefault();
)、ブラウザを自分で立ち上げています。リンクは、aタグのhrefを読みにいっています。
window.open
でも動きますが、アプリ内でハンドリングするためにIonic Native
にあるIn App Browser
を用いて実装しています。なお、普通にブラウザでクリックした場合、In App Browser
の代わりにwindow.open
が立ち上がってくれます。
また、イベント登録が残ったままだとずっとブラウザは監視を続けますので(メモリを使うので)、ページを離脱するタイミングで自動的に実行されるionViewDidLeave()
メソッド内で、登録したイベントの削除を行っています。
ちなみに、app.component.ts
でbodyタグに対してイベント監視をかけてしまうという手抜きなやり方もあります。別にそれほどでかいデメリットはないのですが、予想外のaタグのハンドリングが必要な時などに困りますのであまりおすすめではないですw
それでは、また。
public linkListener
の型付けどうしたらいいのかコメントいただけますと喜びます。