4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Ionic]WKWebViewでaタグをハンドリングする

Last updated at Posted at 2017-10-31

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の型付けどうしたらいいのかコメントいただけますと喜びます。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?