从本机端代码调用 Web 端代码

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

开始之前

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

基本 WebView2 函数

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

API 说明
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 结果
performance.memory {}
(() => { 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 引用。

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

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

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

    await webView.CoreWebView2.ExecuteScriptAsync(text);
    

方案:删除拖放功能

在本部分中,将使用 JavaScript 从 WebView2 控件中删除拖放功能。

首先,请浏览当前的拖放功能:

  1. 创建文件 .txt 以拖放。 例如,创建名为 contoso.txt 的文件并向其添加文本。

  2. F5 生成并运行项目。

  3. contoso.txt 文件拖放到 WebView2 控件中。 此时会打开一个新窗口,这是示例项目中代码的结果:

    拖放contoso.txt的结果

  4. 接下来,添加代码以从 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);");
    
  5. F5 生成并运行项目。

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

方案:删除上下文菜单

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

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

  1. F5 生成并运行项目。

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

    显示默认命令的右键单击菜单

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

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

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

另请参阅