« [Windows 8.1] Windows ストアでギフト カードが利用可能に! 10/18発売 #win8jp | トップページ | [Windows 8.1] ファイルやフォルダのショートカットをスタート画面に表示する #win8jp #windows8 »

2013年10月10日 (木)

[Windows ストア アプリ] Re: Windows 8.1のWebViewで別ブラウザ起動を制御できるか試してみた

Windows 8.1のWebViewで別ブラウザ起動を制御できるか試してみた | 眠るシーラカンスと水底のプログラマー (2013/10/10)

NavigationStartingイベントハンドラーが追加されたので、ページ遷移前に遷移をキャンセルすることができるようになりました。

 「これでtarget=_blank時に別ブラウザアプリが立ち上がるのを制御できるぞかな」

Win 8.1 になって WebView コントロールが随分と改良された話は、 @IT の記事 「特集:次期Windows 8.1&Visual Studio 2013 Preview概説(後編):大きく変わるWindowsストア・アプリ開発 ~ そのほかの変更点」 にも書きました。

だけど、 @coelacanth さんが上のブログ記事で指摘してるように、 a タグに target 属性が指定されていると (つまり、 別ウィンドウに Web ページを開くように設定されていると)、 アプリとは別に IE が開いてそっちに表示されてしまいます。 8.0 のときは画面が完全に切り替わったんですが、 8.1 で横置きだと画面が分割されてアプリと IE の両方が表示されます。

20131010_webview02
※ 左側のアプリ (操作前はフルスクリーン) で、 右下にある 「biac の それさえもおそらくは幸せな日々」 へのリンクをクリックしたところ。 勝手に画面が分割されて、 右半分に IE が立ち上がってそこにリンク先のページが表示された。

フルスクリーン (あるいは、8.0 で言うところの Fill) を前提にしてるアプリだと、 勝手に画面分割されるのは超絶困ります。

てことで、 なんとかしませう。 f(^^;

要は、 HTML をロードしたときに JavaScript で DOM を弄り倒してやればいいんです。 それには、 WebView コントロールの InvokeScriptAsync メソッドが利用できます。

一丁、 サンプルを作ってみましょう。
まずは、 画面に WebView コントロールを置きます。

<WebView x:Name="webView1" Grid.Row="1" Source="http://bluewatersoft.jp/"
         NavigationCompleted="WebView_NavigationCompleted"
         NavigationStarting="WebView_NavigationStarting" />

で、 Web ページが表示された時のイベント ハンドラー NavigationCompleted で、
JavaScript を走らせてやります。

private async void WebView_NavigationCompleted(WebView sender,
    WebViewNavigationCompletedEventArgs args)
{
  // ロードした HTML 中の a タグを全部調べて、 target 属性を全部潰す。
  await webView1.InvokeScriptAsync("eval", new string[]{
@"var anchors = document.getElementsByTagName('a');
for (var i = 0; i < anchors.length; i++) {
  anchors[i].target = '';
}"
  });
}

これで、 どの a タグも WebView コントロールの中で開きます。
※ ただし。 JavaScript で別ウィンドウ開いてくれてるヤツは、 これではダメです。 個別にスクリプトを置き換えことになるのかなぁ。

ついでに。
例えば他のサイトへは移動させたくないとき。 今度は NavigationStarting イベント ハンドラーで制御します。

private async void WebView_NavigationStarting(WebView sender,
    WebViewNavigationStartingEventArgs args)
{
  // 他のサイトへの移動を禁止する。
  // 注意: これだけでは、IE に切り替わるのを防げない。
  if (sender.Source.Host != args.Uri.Host)
  {
    args.Cancel = true;
    await (new Windows.UI.Popups.MessageDialog("異なるサイトへは移動できないよっ!")).ShowAsync();
  }
}

これで実行してみると、 こんな↓感じに。

20131010_webview01

一番右にある 「biac の それさえもおそらくは幸せな日々」へのリンクは、 target="_blank" になっていて、 しかも別のサイトです。 それをクリックしたところ、 目出度くメッセージ ダイアログが表示されました。

|

« [Windows 8.1] Windows ストアでギフト カードが利用可能に! 10/18発売 #win8jp | トップページ | [Windows 8.1] ファイルやフォルダのショートカットをスタート画面に表示する #win8jp #windows8 »

プログラミング」カテゴリの記事

* プログラミング ( Metro スタイル )」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: [Windows ストア アプリ] Re: Windows 8.1のWebViewで別ブラウザ起動を制御できるか試してみた:

« [Windows 8.1] Windows ストアでギフト カードが利用可能に! 10/18発売 #win8jp | トップページ | [Windows 8.1] ファイルやフォルダのショートカットをスタート画面に表示する #win8jp #windows8 »