哪个 WebView2 事件/函数可用于替换 ScriptNotify Webview 事件? [英] Which WebView2 event/function can be use to replace ScriptNotify Webview event?
问题描述
今天,我决定将 WebView
控件迁移到 VB.net 应用程序中的 WebView2
控件.
我已经从 NuGet
安装了 WebView2
并且更改了声明和初始化行(在我的 VB 程序中只有 4 行,因为我使用的是 2 个 WebView2).>
当我构建应用程序时,Visual Studio 2019
指示 ScriptNotify
事件不是 WebView2
的事件!
私有子 wvSelect_ScriptNotify(发送者作为对象,e 作为 WebViewControlScriptNotifyEventArgs) 处理 wvSelect.ScriptNotify
使用旧的 WebView
控件,此事件是使用 windows.external.notify
Javascript 函数生成的.
function clickPlus(e) { window.external.notify("+PLUS:");}
哪个事件正在替换 WebView2
控件中的 ScriptNotify
事件?
我有兴趣了解新事件以及如何从 Javascript 调用此事件.
使用 WebView2:
另请参阅:在 WebView 中使用 JavaScript 进行扩展方案一>.
通用初始化:
- WebView2 实例名为
myWebView2
. - 同样假设使用 WinForms,您还没有指定 GUI 框架
Private Async Sub Load(sender As Object, e as EventArgs) 处理 MyBase.Load等待 myWebView2.EnsureCoreWebView2Async(Nothing)结束子
此外,我正在使用这个简单的类模型,用于反序列化收到的 JSON 消息,因为 WebView2.WebMessageReceived 采用 JSON 格式;不过,你可以传递任何你想要的字符串.
私有类JsonEventMessage公共属性元素作为字符串公共属性值作为字符串结束类
1 - 在这种情况下,javascript 函数已经在 HTML 中定义
<头><script type="text/javascript">函数 SomeFunction(e, v) {var json = JSON.stringify({ 元素:e.target.id, 值:v });window.chrome.webview.postMessage(json);}头部><身体><脚本>document.getElementById("div1").addEventListener("click", function(e) {SomeFunction(e, '+PLUS:')});<div id="div1">要点击的一些文本</div></html>
在这种情况下,您只需要订阅 WebMessageReceived
事件并反序列化 JSON(如果您传递了 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)结束子
注意:我正在使用 e.TryGetWebMessageAsString() 而不是 e.WebMessageAsJson 因为后者用引号括起来(双字符串化).当你传递一个简单的字符串时,它会更好地使用.
2 - 这里,在HEAD
中定义了一个可以通知消息的javascript函数,但没有在其他任何地方添加事件处理程序.
假设您将在运行时添加 HTML 元素,或者您不想在 HTML 或其他任何内容中添加事件处理程序.
<头><script type="text/javascript">函数 SomeFunction(e, v) {var json = JSON.stringify({ 元素:e.target.id, 值:v });window.chrome.webview.postMessage(json);}头部><身体><div id="div1">要点击的一些文本</div></html>
像以前一样订阅 WebMessageReceived
事件和 NavigationCompleted 事件.加载文档时引发此事件.我们需要这个事件,因为在这个例子中,事件处理程序被添加到 Body 中的 Elements 中,这在这之前是不可用的.
在NavigationCompleted
中,我们可以将javascript函数添加到字符串中并调用WebView2.ExecuteScriptAsync() 方法,在 DOM 准备好后执行脚本,否则 GetElementById()
会找不到目标.
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceivedAddHandler myWebView2.NavigationCompleted, AddressOf myWebView2_NavigationCompleted' [...]Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())' [...]结束子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:')});"等待 myWebView2.ExecuteScriptAsync(func)结束子
3 - 这一次,HTML 中的任何地方都没有定义 javascript 函数.
<头>头部><身体><div id="div1">要点击的一些文本</div></html>
案例 1:
像以前一样订阅 WebMessageReceived
和 NavigationCompleted
事件.
在NavigationCompleted
中,将发布消息的javascript函数直接添加到事件处理程序中.调用 ExecuteScriptAsync()
以执行脚本并将事件侦听器添加到 HTML 元素.
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceivedAddHandler myWebView2.NavigationCompleted, AddressOf myWebView2_NavigationCompleted' [...]Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())' [...]结束子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);});"等待 myWebView2.ExecuteScriptAsync(func)结束子
案例 2:
订阅 WebMessageReceived
和 WebView2.CoreWebView2InitializationCompleted.
在本例中,我们向 Document 添加了一个事件侦听器,然后使用 Event.Target
成员和任何其他可用于处理通知的属性或值来确定已单击哪个元素.
在这里,我只是将 [Event].target.id
和 [Event].target.innerText
作为 JSON 属性传递.您当然可以在您的用例中获得任何其他必要的属性.
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceivedAddHandler myWebView2.CoreWebView2InitializationCompleted, AddressOf myWebView2_CoreWebView2InitializationCompleted' [...]Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)Dim message = New JavaScriptSerializer().反序列化(JsonEventMessage)(e.TryGetWebMessageAsString())' [...]结束子私有异步子 myWebView2_CoreWebView2InitializationCompleted(发送者作为对象,e 作为 CoreWebView2InitializationCompletedEventArgs)Dim func as String ="document.addEventListener('点击',功能(e){window.chrome.webview.postMessage(JSON.stringify({元素:e.target.id,值:e.target.innerText}));});"等待 myWebView2.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(func)结束子
Today, I have decided to migrate WebView
control to WebView2
control in a VB.net application.
I have installed WebView2
from NuGet
and I have changed declarations and initialization lines (only 4 lines in my VB program because I'm using 2 WebView2).
When I build my application, Visual Studio 2019
indicates that ScriptNotify
event is not an event of WebView2
!
Private Sub wvSelect_ScriptNotify(
sender As Object,
e As WebViewControlScriptNotifyEventArgs) Handles wvSelect.ScriptNotify
Using old WebView
control, this event is generated using windows.external.notify
Javascript function.
function clickPlus(e) { window.external.notify("+PLUS:"); }
Which event is replacing ScriptNotify
event in WebView2
control?
I'm interested to know the new event and also how this event is called from Javascript.
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
. - 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 (if you passed a JSON object):
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 post the message is added to the event handler directly. Call the 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 of course can 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
这篇关于哪个 WebView2 事件/函数可用于替换 ScriptNotify Webview 事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!