WebBrowserからWebView2へ(3)

WEBVIEW2を使用してみる(3)マウスクリックイベントの連携と要素情報の取得

前回に続いて、ようやくWebView2のDOM操作の試運転にはいってみる。

やってみたいこと
・ WebView2へ表示したサイトのマウスイベントへ処理を入れる。
  とりあえずマウスクリックでテスト。
・ マウスクリックされたHTML要素のタグやクラス情報をVB側で取得
・ 取得した情報をMsgBoxでポップアップ

開発環境

・ Windows10
・ Microsoft Visual Studio 2019 (VB .NET)

マウスクリックイベント

WebBrowserだと、
AddHandler WebBrowser.Document.Body.MouseUp, AddressOf “任意関数”
とかでVBで書いた関数とかにイベント紐付けれたけど、
WebView2だとJavaScriptを設定してあげてイベント処理の実装するみたい。

下の例はJavaScriptでonclickイベントにalertメッセージを表示する簡単な処理を
ExecuteScriptAsyncメソッドで設定してあげる。

Dim jsClickEvent As New System.Text.StringBuilder()
jsClickEvent.AppendLine("document.body.onclick = function(event) { ")
jsClickEvent.AppendLine("  alert('Click!');")
jsClickEvent.AppendLine("}; ")
Await webview.ExecuteScriptAsync(jsClickEvent.ToString())

クリック時に無事メッセージ表示されるの確認

JavaScriptからの戻り値取得

VB側からブラウザに対してのイベント設定は確認できたけど、
ブラウザ側からVBへの値渡しもできないと一方通行で連携とはいえない。

方法は何個かあるみたいだけど今回はWebMessageReceivedイベントを使ってみる。
JavaScript側からメッセージを受信したときに発生するイベントなので
今回作りたい機能的にマウスクリックされた要素情報を取得するのに使えそう。

まず組み込むJavaScriptの中にpostMessageメソッドを仕込んどいて、
戻り値情報をWebView2へかえすようにする。

下例ではJavaScriptコード内でタグ名、クラス名なんかを返すようにしてる。
return false;はリンククリックしたときのサイト遷移防止用

Dim jsClickEvent As New System.Text.StringBuilder()
jsClickEvent.AppendLine("document.body.onclick = function(event) { ")
jsClickEvent.AppendLine("  window.chrome.webview.postMessage(" &
                        "'[TagName]   ' + " & "event.target.tagName + " &
                        "'\n[ClassName] ' + " & "event.target.className + " &
                        "'\n[innertext] ' + " & "event.target.innerText" &
                        "); ")
jsClickEvent.AppendLine("  return false;")
jsClickEvent.AppendLine("}; ")
Await Me.ExecuteScriptAsync(jsClickEvent.ToString())

前回作ったClsWebViewへWebMessageReceivedイベントを追加。
受け取った情報はMsgBoxで表示。

Private Sub MessageReceived(sender As Object, args As Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgs) Handles Me.WebMessageReceived
    Dim text As String = args.TryGetWebMessageAsString()
    MsgBox(text)
End Sub

サンプルコード

前回作ったClsWebViewへJavaScriptイベント追加用の関数と受信イベントを追記
ClsWebView.vb

''' <summary>
''' サイト内にJavaScriptイベント追加
''' </summary>
Public Async Sub AddJsEvent()
    Dim jsClickEvent As New System.Text.StringBuilder()
    jsClickEvent.AppendLine("document.body.onclick = function(event) { ")
    jsClickEvent.AppendLine("  window.chrome.webview.postMessage(" &
                            "'[TagName]   ' + " & "event.target.tagName + " &
                            "'\n[ClassName] ' + " & "event.target.className + " &
                            "'\n[innertext] ' + " & "event.target.innerText" &
                            "); ")
    jsClickEvent.AppendLine("  return false;")
    jsClickEvent.AppendLine("}; ")
    Await Me.ExecuteScriptAsync(jsClickEvent.ToString())
End Sub

''' <summary>
''' JavaScriptからメッセージを受信したときに実行されるイベント
''' </summary>
''' <param name="sender"></param>
''' <param name="args"></param>
Private Sub MessageReceived(sender As Object, args As Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgs) Handles Me.WebMessageReceived
    Dim text As String = args.TryGetWebMessageAsString()
    MsgBox(text)
End Sub

Form1側は、フォームロードで設定していたボタンクリックイベントをちょっと改造
サイト遷移完了後にイベント設定する。
Form1.vb

'イベント設定:ボタンクリック時、サイト遷移開始
AddHandler navigateBtn.Click,
    Async Sub()

        '初期化終えてから処理
        If webview Is Nothing OrElse webview.CoreWebView2 Is Nothing Then
            MsgBox("コントロール初期化中です")
            Exit Sub
        End If

        '指定URLへ遷移
        webview.CoreWebView2.Navigate("https://www.google.com")

        '待機処理
        Await webview.WaitNavigating

        '遷移完了後のURLとステータスをデバッグ出力
        Debug.Print("URL:" & webview.Source.OriginalString & " | STATUS:" & webview.NowStatus)

        'サイト内にJavaScriptイベント追加
        Call webview.AddJsEvent()

    End Sub

「Gmail」のところをクリックして、要素情報でることを確認。
連携もなんとかできそうですね。


次回は要素操作なんかを試してみたいと思います。

タイトルとURLをコピーしました