A few possible scenarios to handle event notifications with WebView2:
See also: Use JavaScript in WebView for extended scenarios.
Generic initialization:
- The WebView2 instance is named
myWebView2.
- Using basic methods: for example, the JSON deserialization is performed using JavaScriptSerializer. You probably have Json.Net or System.Text.Json instead.
- Also assuming WinForms, you haven't specified the GUI framework
Private Async Sub Load(sender As Object, e as EventArgs) Handles MyBase.Load
await myWebView2.EnsureCoreWebView2Async(Nothing)
End Sub
Also, I'm using this simple class model, used to deserialize the JSON message received, since WebView2.WebMessageReceived assumes a JSON format; you can pass whatever string you want, though.
Private Class JsonEventMessage
Public Property Element As String
Public Property Value As String
End Class
1 - In this scenario, javascript Functions are already defined in the HTML
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function SomeFunction(e, v) {
var json = JSON.stringify({ Element:e.target.id, Value:v });
window.chrome.webview.postMessage(json);
}
</script>
</head>
<body>
<script>
document.getElementById("div1").addEventListener("click", function(e) {SomeFunction(e, '+PLUS:')});
</script>
<div id="div1">Some Text to Click</div>
</body>
</html>
In this case, you just need to subscribe to the WebMessageReceived event and deserialize the JSON:
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
Console.WriteLine(message.Element)
Console.WriteLine(message.Value)
End Sub
Note: I'm using e.TryGetWebMessageAsString() and not e.WebMessageAsJson since the latter is enclosed in quotes (double-stringified). It's better used when you pass a simple string.
2 - Here, a JavaScript Function that can notify a message is defined in HEAD, but no event handlers are added anywhere else.
Assume you will add HTML Elements at run-time or you don't want to add the event handlers in the HTML or anything else.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function SomeFunction(e, v) {
var json = JSON.stringify({ Element:e.target.id, Value:v });
window.chrome.webview.postMessage(json);
}
</script>
</head>
<body>
<div id="div1">Some Text to Click</div>
</body>
</html>
Subscribe to the WebMessageReceived event as before and to the NavigationCompleted event. This event is raised when the Document is loaded. We need this event, since, in the example, the event handlers are added to Elements in the Body, which is not available before this point.
In NavigationCompleted, we can add the JavaScript Function to a string and call the WebView2.ExecuteScriptAsync() method, which executes the script after the DOM is ready, otherwise GetElementById() would not find the target.
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
AddHandler myWebView2.NavigationCompleted, AddressOf myWebView2_NavigationCompleted
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
' [...]
End Sub
Private Async Sub myWebView2_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
Dim func As String =
"document.getElementById('div1').
addEventListener('click', function(e) {
SomeFunction(e, '+PLUS:')
});"
Await myWebView2.ExecuteScriptAsync(func)
End Sub
3 - This time, no JavaScript Functions are defined anywhere in the HTML.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="div1">Some Text to Click</div>
</body>
</html>
Case 1:
Subscribe to the WebMessageReceived and NavigationCompleted events as before.
In NavigationCompleted, the JavaScript Function that posts the message is added to the event handler directly. Call ExecuteScriptAsync() to execute the script and add the Event Listener to a HTML Element.
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
AddHandler myWebView2.NavigationCompleted, AddressOf myWebView2_NavigationCompleted
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
' [...]
End Sub
Private Async Sub myWebView2_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
Dim func As String =
"document.getElementById('div1').
addEventListener('click', function(e) {
var json = JSON.stringify({Element:e.target.id, Value:'+PLUS:'});
window.chrome.webview.postMessage(json);
});"
Await myWebView2.ExecuteScriptAsync(func)
End Sub
Case 2:
Subscribe to the WebMessageReceived and WebView2.CoreWebView2InitializationCompleted.
In this case, we're adding an event listener to the Document, then determine which Element has been clicked using the Event.Target member and any other property or value that can be useful to handle the notification.
Here, I'm simply passing the [Event].target.id and [Event].target.innerText as JSON properties. You can of course get any other attribute necessary in your use-case.
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
AddHandler myWebView2.CoreWebView2InitializationCompleted, AddressOf myWebView2_CoreWebView2InitializationCompleted
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().
Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
' [...]
End Sub
Private Async Sub myWebView2_CoreWebView2InitializationCompleted(
sender As Object,
e As CoreWebView2InitializationCompletedEventArgs)
Dim func as String =
"document.addEventListener
('click', function(e) {
window.chrome.webview.postMessage(
JSON.stringify({ Element:e.target.id, Value:e.target.innerText })
);
});"
Await myWebView2.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(func)
End Sub