在 WebView2 控件中使用 JavaScript 可以自定义本机应用以满足要求。 本文探讨如何在 WebView2 中使用 JavaScript,并回顾如何使用高级 WebView2 特性和函数进行开发。

本文假定你已有一个工作项目。 如果没有项目,并且想要继续学习,请参阅 WebView2 入门

基本 WebView2 函数

使用以下函数开始在 WebView2 应用中嵌入 JavaScript。

ExecuteScriptAsync 在 WebView2 控件中运行 JavaScript。 在页面 文档对象模型 (DOM) 加载内容 完成导航 后调用此方法。 请参阅 WebView2 入门 AddScriptToExecuteOnDocumentCreatedAsync 创建 DOM 时,在每个页面上运行。 初始化 CoreWebView2 后调用此方法。

方案:ExecuteScript JSON 编码的结果

由于 的结果 ExecuteScriptAsync 是 JSON 编码的,因此如果计算 JavaScript 的结果是字符串,则会收到 JSON 编码的字符串,而不是字符串的值。

例如,以下代码执行生成字符串的脚本。 生成的字符串包括开头的引号、末尾的引号和转义斜杠:

string result = await coreWebView2.ExecuteScriptAsync(@"'example'");
Debug.Assert(result == "\"example\"");

该脚本将返回一个 JSON 编码的字符串 ExecuteScript 。 如果从脚本调用 JSON.stringify ,则结果将双重编码为 JSON 字符串,其值为 JSON 字符串。

JSON 编码的对象中仅包含直接位于结果中的属性;继承的属性不包括在 JSON 编码的对象中。 大多数 DOM 对象继承所有属性,因此需要将其值显式复制到另一个对象中以返回。 例如:

Script (() => { const {totalJSHeapSize, usedJSHeapSize} = performance.memory; return {totalJSHeapSize, usedJSHeapSize}; })(); {"totalJSHeapSize":4434368,"usedJSHeapSize":2832912}

performance.memory 返回时,在结果中看不到它的任何属性,因为所有属性都是继承的。 如果相反,我们将特定属性值从 performance.memory 复制到我们自己的新对象中以返回,则我们在结果中看到这些属性。

通过 ExecuteScriptAsync 该脚本执行脚本时,在全局上下文中运行。 它有助于将脚本置于匿名函数中,以便定义的任何变量不会污染全局上下文。

  • 如果多次运行脚本 const example = 10; ,则后续运行该脚本的时间将引发异常,因为 example 是在首次运行脚本时定义的。

  • 如果改为运行脚本 (() => { const example = 10; })(); ,则会 example 在该匿名函数的上下文中定义变量。 这样,它就不会污染全球上下文,并且可以多次运行。

    方案:运行专用脚本文件

    在本部分中,你将从 WebView2 控件访问专用 JavaScript 文件。

    尽管内联编写 JavaScript 对于快速 JavaScript 命令可能有效,但会丢失 JavaScript 颜色主题和行格式,这使得在 Visual Studio 中编写大段代码变得困难。

    若要解决此问题,请使用代码创建单独的 JavaScript 文件,然后使用参数传递对该文件的 ExecuteScriptAsync 引用。

  • 在项目中创建文件 .js ,并添加要运行的 JavaScript 代码。 例如,创建名为 的文件 script.js

  • 通过在页面导航完成后粘贴以下代码,将 JavaScript 文件转换为传递给 ExecuteScriptAsync的字符串:

    string text = System.IO.File.ReadAllText(@"C:\PATH_TO_YOUR_FILE\script.js");
    
  • 使用 ExecuteScriptAsync传递文本变量:

    await webView.CoreWebView2.ExecuteScriptAsync(text);
    
  • 接下来,添加代码以从 WebView2 控件中删除拖放功能。 在代码中初始化 CoreWebView2 对象后粘贴以下代码:

    await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(
       "window.addEventListener('dragover',function(e){e.preventDefault();},false);" +
       "window.addEventListener('drop',function(e){" +
          "e.preventDefault();" +
          "console.log(e.dataTransfer);" +
          "console.log(e.dataTransfer.files[0])" +
       "}, false);");
    
  • F5 生成并运行项目。

  • 尝试拖放 contoso.txt 到 WebView2 控件中。 确认无法拖放。

    方案:删除上下文菜单

    在本部分中,将从 WebView2 控件中删除右键单击菜单。

    若要开始,请浏览右键单击菜单的当前功能:

  • F5 生成并运行项目。

  • 右键单击 WebView2 控件上的任意位置。 上下文菜单显示默认的右键单击菜单命令:

    接下来,添加代码以从 WebView2 控件中删除右键单击菜单功能。

  • 在代码中初始化 CoreWebView2 对象后粘贴以下代码:

    await webView.CoreWebView2.ExecuteScriptAsync("window.addEventListener('contextmenu', window => {window.preventDefault();});");
    
  • F5 生成并运行项目。 确认无法打开右键单击菜单。

  • WebView2 入门
  • WebView2Samples 存储库 - WebView2 功能的综合示例。
  • WebView2 API 参考
  • WebView2 功能和 API 概述中的 Web/本机互操作
  •