WebView2 JS注入返回空json字符串



与WebView2针对Windows,我试图设置我自己的上下文菜单。通过选定文本或通过鼠标单击所指向的基础元素。

但是,我不能通过鼠标操作甚至通过byId获得DOM元素。我认为我的JavaScript注入或WebView属性设置是错误的,但不太确定。谁能给我一个建议吗?

版本信息。

  • 操作系统:Windows 10 Pro 21H2 19044.1682
  • Visual Studio: Community 2022 17.1.6
  • webview: 1.0.1185.39
  • 项目属性:目标框架=。NET 6.0;目标操作系统版本=10.0.19041.0

下面是测试代码

using Microsoft.Web.WebView2.Core;
namespace WinFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
HTML(@"C:temptest.html");
}
public void HTML(string url)
{
webView21.CoreWebView2InitializationCompleted += WebView2Control_CoreWebView2InitializationCompleted;
webView21.Source = new Uri(url);
}
private void WebView2Control_CoreWebView2InitializationCompleted(object? sender, CoreWebView2InitializationCompletedEventArgs e)
{
if (!e.IsSuccess)
{
MessageBox.Show($"WebView2 creation failed, with exception : {e.InitializationException}");
return;
}
// subscribe to events we are interested in
webView21.CoreWebView2.ContextMenuRequested += CoreWebView2_ContextMenuRequested;       // user clicked right mouse to show context menu
}
private async void CoreWebView2_ContextMenuRequested(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2ContextMenuRequestedEventArgs e)
{
IList<CoreWebView2ContextMenuItem> menuItemList = e.MenuItems;
menuItemList.Clear();  // clear default menu items, like prev, next, property
//GETTING SELECTED TEXT
string text = e.ContextMenuTarget.HasSelection ? e.ContextMenuTarget.SelectionText : ""; // it works
if (string.IsNullOrEmpty(text))  // no text selection, then examine DOM
{
//GET AN UNDERLYING ELEMENT FROM MOUSE POINT
var result = await webView21.CoreWebView2.ExecuteScriptAsync($"document.elementFromPoint({e.Location.X},{e.Location.Y})");   //it doesn't work, just returns an empty JSON text (not null)
//var result = await webView21.CoreWebView2.ExecuteScriptAsync("function foo(){return 'foo() gets called';}; foo();");  //for testing purpose, it works
//var result = await webView21.CoreWebView2.ExecuteScriptAsync("function foo(){return document.getElementById('table-content'};foo();)");   //it returns an empty result
}
// TO DO
// setup menuItem tree based on the result we got
//......
//......
e.Handled = true;
}
}
}

我想我做到了,谢谢你的见解。我最初的意图是捕获innerText和href,并将它们提供给c#代码(主机)。一个音符。Getter/setter必须准备好。下面是完整的测试代码。

using Microsoft.Web.WebView2.Core;
using System.Text.Json;
namespace WinFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
HTML(@"C:temptest.html");
}
public void HTML(string url)
{
webView21.CoreWebView2InitializationCompleted += WebView2Control_CoreWebView2InitializationCompleted;
this.webView21.Source = new Uri(url);
}
private void WebView2Control_CoreWebView2InitializationCompleted(object? sender, CoreWebView2InitializationCompletedEventArgs e)
{
if (!e.IsSuccess)
{
MessageBox.Show($"WebView2 creation failed, with exception : {e.InitializationException}");
return;
}
// subscribe to events we are interested in
webView21.CoreWebView2.ContextMenuRequested += CoreWebView2_ContextMenuRequested;       // user clicked right mouse to show context menu
}
public class HTMLelements
{
public string href { get; set; } = "";
public string innerText { get; set; } = "";
}
private async void CoreWebView2_ContextMenuRequested(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2ContextMenuRequestedEventArgs e)
{
IList<CoreWebView2ContextMenuItem> menuItemList = e.MenuItems;
menuItemList.Clear();  // clear default menu items, like prev, next, property
HTMLelements htmlElements = new(); //Didn't know this new syntax
//GETTING SELECTED TEXT
htmlElements.innerText = e.ContextMenuTarget.HasSelection ? e.ContextMenuTarget.SelectionText : "";
if (string.IsNullOrEmpty(htmlElements.innerText))  // no text selection, then examine DOM
{
//GETTING AN UNDERLYING ELEMENT FROM MOUSE POINT
//it should return JSON string { "href" : "something or empty", "innerText: "something" }
string jScript = $@"
function GetElement() {{
var elem = document.elementFromPoint({ e.Location.X},{ e.Location.Y});
var obj = new Object();
obj.href = elem.href === undefined? '' : elem.href;
obj.innerText = elem.innerText;
return obj;
}};
GetElement();";
var result = await webView21.CoreWebView2.ExecuteScriptAsync(jScript);
htmlElements = JsonSerializer.Deserialize<HTMLelements>(result); // feed them to our class object
}
// TO DO
//setup menuItem tree based on the result we got
//setting up CoreWebView2ContextMenuItem is new to me, hence I use C# standard toolStripMenuItem instead.
//sometime later, I will amend as such
toolStripMenuItemPlaceHolder.Text = htmlElements.innerText;
toolStripMenuItemPlaceHolder.Enabled = true;
if (!string.IsNullOrEmpty(htmlElements.href))
{
toolStripMenuItemPlaceHolder.Tag = htmlElements.href;
toolStripMenuItemShowInBrowser.Enabled = true;
}
else
{
toolStripMenuItemPlaceHolder.Tag = null;
toolStripMenuItemShowInBrowser.Enabled = false;
}
contextMenuStripInBrowser.Show(webView21, e.Location);
e.Handled = false;
}
}
}

最新更新