.NET混合開發解決方案10 WebView2控制元件呼叫網頁JS方法

張傳寧發表於2022-05-09

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編碼的字串,而不是字串的值。例如,以下程式碼執行導致字串的指令碼。 生成的字串包括開頭的引號、末尾的引號和轉義斜槓:

.NET混合開發解決方案10 WebView2控制元件呼叫網頁JS方法

.NET混合開發解決方案10 WebView2控制元件呼叫網頁JS方法

如果從指令碼呼叫 JSON.stringify ,則結果將作為 JSON 字串進行雙重編碼,其值為 JSON 字串。

.NET混合開發解決方案10 WebView2控制元件呼叫網頁JS方法

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

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

.NET混合開發解決方案10 WebView2控制元件呼叫網頁JS方法

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

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

.NET混合開發解決方案10 WebView2控制元件呼叫網頁JS方法

通過 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專案

調整頁面邏輯

執行程式並測試

.NET混合開發解決方案10 WebView2控制元件呼叫網頁JS方法

WebView2呼叫JS方法的邏輯

.NET混合開發解決方案10 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();});");

開發者還可以執行其他自定義指令碼來設定網頁的效果。

相關文章