是的,可以 100% 将脚本添加到您的环境中,这些脚本可以拦截和控制您正在呈现的内容。
我在 windows 窗体中使用 WebView2,所以我将向您展示我是如何在桌面 windows 窗体应用程序中执行此操作的,该过程对于其他环境将类似,并且对于 WPF 项目几乎相同。
步骤 1
设置和初始化 webview2 控件的默认设置
public FrmMainForm()
{
InitializeComponent();
// Resize/position client to a standard 720p HD TV and make room for tools
var toolBarSize =
PnlToolPanelTopRow.Height +
PnlToolPanelLowerRow.Height;
SetClientSizeCore(1280, toolBarSize + 720);
//webview.Top = toolBarSize;
webview.Height = 720;
// Webview initialisation handler, called when control instatiated and ready
webview.CoreWebView2InitializationCompleted += Webview_CoreWebView2InitializationCompleted;
// Set defaults for tools
TxtAppUrl.Text = "http://app/";
TxtUserAgent.Text = DEFAULTUA;
}
注意初始化完成事件附带的“初始化处理程序”。
第二步
在您的初始化事件处理程序中,您需要在每次初始化浏览器视图时加载您希望运行的 JavaScript。这些脚本总是在加载页面中的任何脚本之前执行,或者在 dom 加载之前执行,但是它们在页面导航之后执行,因此您不能使用它们来控制导航周期。
这是一个例子,来自我的一个项目
private void Webview_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{
// Custom URL handler (All URLS starting "http://app/" are intercepted directly by the application
webview.CoreWebView2.AddWebResourceRequestedFilter("http://app/*", CoreWebView2WebResourceContext.All);
webview.CoreWebView2.WebResourceRequested += WebResourceRequested;
// Load in our custom JS API files to create the HbbTv JS environment
webview.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(JsLoader.LoadApi("BrowserOverrides.js"));
// Assign any back end C sharp classes to support our JS api's
webview.CoreWebView2.AddHostObjectToScript("channelData", new ChannelData());
// Event handler for notification of dom content load finished
//webview.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded;
// Show dev tools by default
webview.CoreWebView2.OpenDevToolsWindow();
// Other misc settings
webview.CoreWebView2.Settings.UserAgent = DEFAULTUA;
}
你需要注意的那一行是这样的:
webview.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(JsLoader.LoadApi("BrowserOverrides.js"));
我使用一个自定义加载器类,它从编译到我的应用程序中的资源中获取我的 java 脚本文件,但是您不需要,传递给 AddScript 调用的唯一参数只是一个普通的 java 字符串脚本代码,例如:
webview.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("alert('hello world');");
将导致您的 webview2 会话在每次导航之后,但在页面中的 dom 和脚本加载并运行之前,对于在 webview 中浏览到的每个页面显示警报。
JS 代码可以完全访问浏览器环境,因此只需将常规 JS 处理程序附加到“dom 加载”或“页面加载”常规 java 脚本事件之一,然后使用标准 dom 操作来查找您想要的元素并将其显示样式设置为“无”。
第 3 步(可选)
您还将从我的第二个代码 sn-p 中看到,还有 2 个可以使用的挂钩点。
webview.CoreWebView2.AddHostObjectToScript("channelData", new ChannelData());
将我的自定义 C# 类类型“ChannelData”添加到浏览器环境中,然后通过以下 JS 代码将其提供给浏览器
chrome.webview.hostObjects.channelData.(method name or property name accessible here)
“channelData”名称,在“hostObjects”之后与“AddHostObject”调用的第一个参数中使用的相同,第二个消息是一个必须设置如下的常规C#类:
using HbbTvBrowser.DataClasses;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
namespace JsSupportClasses
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class (Class Name Here)
{
public string SomeMethod()
{
return JsonConvert.SerializeObject(Some C# objects to return);
}
}
}
如果没有提供类接口和com可见属性,则该类将不会被Web视图看到并且不可调用。
你的方法返回给 JS 代码的任何数据,必须是简单的数据类型,例如 int、bool 或 string,这意味着你不能返回复杂的对象而不先序列化它们,然后在你返回后反序列化它们JS土地。
您会注意到还有一个 C# 级别的 dom 就绪处理程序。一旦 HTML 被加载并准备好被访问,但在图像、脚本、css 或其他类似的东西被加载之前,它就会被触发。但是,您不能从 C# 更改 dom 内容,至少目前不能,我相信今年某个时候它可能会出现在团队的雷达上,但我无法确认。
虽然我自己不需要这样做,但我确实相信可以在 C# 中获取已加载 HTML 的副本,但这只是“副本”,更改它不会更改实际加载 dom。