.NET混合開發解決方案10 WebView2控制項調用網頁JS方法

WebView2控制項應用詳解系列部落格

.NET桌面程式集成Web網頁開發的十種解決方案 

.NET混合開發解決方案1 WebView2簡介

.NET混合開發解決方案2 WebView2與Edge瀏覽器的區別

.NET混合開發解決方案3 WebView2的進程模型

.NET混合開發解決方案4 WebView2的執行緒模型

.NET混合開發解決方案5 WebView2運行時與分發應用

.NET混合開發解決方案7 WinForm程式中通過NuGet管理器引用集成WebView2控制項

.NET混合開發解決方案8 WinForm程式中通過設置固定版本運行時的BrowserExecutableFolder屬性集成WebView2控制項

.NET混合開發解決方案9 WebView2控制項的導航事件

  客戶端程式(WinForm、WPF、Win32、WinUI)集成WebView控制項載入Web完成後,還有兩種常見的需求

  • C#調用JS方法
    • 執行通用方法,設置網頁特效。
    • 調用網頁中定義的JS方法,執行計算等。
  • JS調用C#方法

本文講解第一種需求的實現方式。

WebView2控制項提供了2個方法用於執行JavaScript腳本

ExecuteScriptAsync() 執行自定義腳本

  由於ExecuteScriptAsync()的結果是JSON編碼的,所以如果計算JavaScript的結果是一個字元串,那麼將收到一個JSON編碼的字元串,而不是字元串的值。例如,以下程式碼執行導致字元串的腳本。 生成的字元串包括開頭的引號、末尾的引號和轉義斜杠:

如果從腳本調用 JSON.stringify ,則結果將作為 JSON 字元串進行雙重編碼,其值為 JSON 字元串。

只有直接在結果中的屬性包含在 JSON 編碼的對象中;繼承的屬性不包括在 JSON 編碼的對象中。 大多數 DOM 對象繼承所有屬性,因此需要將它們的值顯式複製到另一個對象中才能返回。 例如:

執行 performance.memory 返回時由於所有屬性都是繼承的,因此在結果中看不到其任何屬性。 

如果改為將特定屬性值從 performance.memory 複製到自己的新對象中返回,則會在結果中看到這些屬性。

(() => { const {totalJSHeapSize, usedJSHeapSize} = performance.memory; return {totalJSHeapSize, usedJSHeapSize}; })();

通過 ExecuteScriptAsync()執行腳本時,會在全局上下文中運行。 將腳本置於匿名函數中有助於使定義的任何變數不會污染全局上下文。

ExecuteScriptAsync() 執行專用腳本文件

  如果將js的邏輯寫在字元串中,相對來說寫的時候比較困難,如沒有語法提示、邏輯檢查等,因此很難在Visual Studio中編寫大量程式碼。若要解決此問題,請使用程式碼創建單獨的 JavaScript 文件,然後使用參數傳遞對該文件的 ExecuteScriptAsync 引用。

1、在項目中創建JS文件,並添加要運行的 JavaScript 程式碼。如 script.js。

2、將 JavaScript 文件轉換為傳遞到 ExecuteScriptAsync的字元串,方法是在頁面導航完成後粘貼以下程式碼:

string text = System.IO.File.ReadAllText(@"C:\XXXX\script.js");

3、使用以下方法 ExecuteScriptAsync傳遞文本變數:

await webView.CoreWebView2.ExecuteScriptAsync(text);
ExecuteScriptAsync() 執行目標網頁中的JS方法

1、新建一個WebFom項目

調整頁面邏輯

運行程式並測試

WebView2調用JS方法的邏輯

AddScriptToExecuteOnDocumentCreatedAsync() 設置網頁特效

WebView2控制項載入網頁後,如果將一個文件(如:script.js、script.txt等)拖拽到WebView2控制項上,將自動執行文件,效果如下

可以通過webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync()方法運行腳本禁用拖拽功能

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);");

再次運行後,拖拽文件為WebView2控制項上無任何反應,說明拖拽功能已被禁用

使用 webView2.CoreWebView2.ExecuteScriptAsync() 方法執行上述腳本同樣可以達到相同的效果。

還可以執行腳本來禁用網頁右鍵菜單功能

await webView.CoreWebView2.ExecuteScriptAsync("window.addEventListener('contextmenu', window => {window.preventDefault();});");

開發者還可以執行其他自定義腳本來設置網頁的效果。