WebView2控制元件應用詳解系列部落格
.NET混合開發解決方案2 WebView2與Edge瀏覽器的區別
.NET混合開發解決方案5 WebView2執行時與分發應用
.NET混合開發解決方案7 WinForm程式中通過NuGet管理器引用整合WebView2控制元件
.NET混合開發解決方案8 WinForm程式中通過設定固定版本執行時的BrowserExecutableFolder屬性整合WebView2控制元件
客戶端程式(WinForm、WPF、Win32、WinUI)整合WebView控制元件載入Web完成後,還有兩種常見的需求
- C#呼叫JS方法
- 執行通用方法,設定網頁特效。
- 呼叫網頁中定義的JS方法,執行計算等。
- JS呼叫C#方法
本文講解第一種需求的實現方式。
WebView2控制元件提供了2個方法用於執行JavaScript指令碼
- ExecuteScriptAsync
- 在 WebView2 控制元件中執行 JavaScript。 載入頁面文件物件模型(DOM)內容或完成導航後呼叫此方法。
- AddScriptToExecuteOnDocumentCreatedAsync
- 建立 DOM 時,在每個頁面上執行。 初始化 CoreWebView2 後呼叫此方法。
由於ExecuteScriptAsync()的結果是JSON編碼的,所以如果計算JavaScript的結果是一個字串,那麼將收到一個JSON編碼的字串,而不是字串的值。例如,以下程式碼執行導致字串的指令碼。 生成的字串包括開頭的引號、末尾的引號和轉義斜槓:
如果從指令碼呼叫 JSON.stringify
,則結果將作為 JSON 字串進行雙重編碼,其值為 JSON 字串。
只有直接在結果中的屬性包含在 JSON 編碼的物件中;繼承的屬性不包括在 JSON 編碼的物件中。 大多數 DOM 物件繼承所有屬性,因此需要將它們的值顯式複製到另一個物件中才能返回。 例如:
執行 performance.memory
返回時由於所有屬性都是繼承的,因此在結果中看不到其任何屬性。
如果改為將特定屬性值從 performance.memory
複製到自己的新物件中返回,則會在結果中看到這些屬性。
(() => { const {totalJSHeapSize, usedJSHeapSize} = performance.memory; return {totalJSHeapSize, usedJSHeapSize}; })();
通過 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);
1、新建一個WebFom專案
調整頁面邏輯
執行程式並測試
WebView2呼叫JS方法的邏輯
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();});");
開發者還可以執行其他自定義指令碼來設定網頁的效果。