從原生端程式碼呼叫 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 物件會繼承所有屬性,因此網頁端程式碼必須明確地將屬性的值複製到另一個物件中,並將該物件傳回至原生端程式碼。 例如:

指令碼 結果
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,變數會定義在該匿名函數的內容中。 這樣,它就不會污染全球環境,並且可以運行多次。

案例:執行專用 JavaScript 檔案

您可以從 WebView2 控制項存取專用的 JavaScript 檔案。

內嵌 JavaScript 程式碼適用於快速 JavaScript 命令。 不過,內嵌 JavaScript 程式碼不支援代碼編輯器中的色彩佈景主題和線條格式設定。 這會使得撰寫大量程式碼變得困難,例如在 Visual Studio 中撰寫。

若要解決此問題,請建立包含您程式碼的單獨 JavaScript 檔案,然後使用參數將 ExecuteScriptAsync 參照傳遞給該檔案。

若要建立和使用個別的專用 JS 檔案:

  1. 在專案中建立 .js 檔案,並新增您要執行的 JavaScript 程式碼。 例如,建立名為 的檔案 script.js。

  2. 在頁面瀏覽完成後,貼上下列程式碼,將 JavaScript 檔案轉換成傳遞至 ExecuteScriptAsync的字串:

    string text = System.IO.File.ReadAllText(@"C:\PATH_TO_YOUR_FILE\script.js");
    
  3. 將變數傳遞 text 給 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 以組建及執行專案。 確認您無法開啟快顯功能表。

另請參閱