跳到主要內容

Handles

簡介

Playwright 可以在頁面 DOM 元素或頁面內部的任何其他物件建立 handles。這些 handles 存在於 Playwright 進程中,而實際的物件則存在於瀏覽器中。Handles 有兩種型別:

  • JSHandle 參考頁面中的任何 JavaScript 物件
  • ElementHandle 參考頁面中的 DOM 元素,它具有額外的方法,允許對元素執行動作並斷言其屬性。

由於頁面中的任何 DOM 元素也是 JavaScript 物件,因此任何 ElementHandle 也都是 JSHandle

Handles 用於對頁面中那些實際物件執行操作。您可以在 handle 上評估、取得 handle 屬性、將 handle 作為評估參數傳遞、將頁面物件序列化為 JSON 等。請參閱 JSHandle 類別 API 以了解這些方法。

API 參考

以下是取得 JSHandle 最簡單的方法。

var jsHandle = await page.EvaluateHandleAsync("window");
// Use jsHandle for evaluations.

元素 Handles

不建議使用

不建議使用 ElementHandle,請改用 Locator 物件和 web-first 斷言。

當需要 ElementHandle 時,建議使用 Page.WaitForSelectorAsync()Frame.WaitForSelectorAsync() 方法來取得。這些 API 會等待元素附加並可見。

// Get the element handle
var jsHandle = await page.WaitForSelectorAsync("#box");
var elementHandle = jsHandle as ElementHandle;

// Assert bounding box for the element
var boundingBox = await elementHandle.BoundingBoxAsync();
Assert.AreEqual(100, boundingBox.Width);

// Assert attribute for the element
var classNames = await elementHandle.GetAttributeAsync("class");
Assert.True(classNames.Contains("highlighted"));

將 handles 作為參數

Handles 可以傳遞到 Page.EvaluateAsync() 和類似的方法中。以下程式碼片段在頁面中建立一個新的陣列,使用資料初始化它,並將此陣列的 handle 傳回 Playwright。然後在後續的評估中使用該 handle

// Create new array in page.
var myArrayHandle = await page.EvaluateHandleAsync(@"() => {
window.myArray = [1];
return myArray;
}");

// Get the length of the array.
var length = await page.EvaluateAsync<int>("a => a.length", myArrayHandle);

// Add one more element to the array using the handle
await page.EvaluateAsync("arg => arg.myArray.add(arg.newElement)",
new { myArray = myArrayHandle, newElement = 2 });

// Release the object when it is no longer needed.
await myArrayHandle.DisposeAsync();

Handle 生命周期

可以使用頁面方法(例如 Page.EvaluateHandleAsync()Page.QuerySelectorAsync()Page.QuerySelectorAllAsync())或其框架對應方法 Frame.EvaluateHandleAsync()Frame.QuerySelectorAsync()Frame.QuerySelectorAllAsync() 來取得 Handles。一旦建立,handles 將保留來自 垃圾回收 的物件,除非頁面導航或 handle 通過 JsHandle.DisposeAsync() 方法手動處置。

API 參考

Locator vs ElementHandle

注意

我們僅建議在極少數情況下使用 ElementHandle,即當您需要在靜態頁面上執行廣泛的 DOM 遍歷時。對於所有使用者動作和斷言,請改用 locator。

LocatorElementHandle 之間的區別在於,後者指向特定的元素,而 Locator 則捕捉如何檢索該元素的邏輯。

在以下範例中,handle 指向頁面上的特定 DOM 元素。如果該元素變更文字,或被 React 用於渲染完全不同的元件,則 handle 仍然指向該非常陳舊的 DOM 元素。這可能會導致意外的行為。

var handle = await page.QuerySelectorAsync("text=Submit");
await handle.HoverAsync();
await handle.ClickAsync();

使用 locator,每次使用 locator 時,都會使用選擇器在頁面中定位最新的 DOM 元素。因此,在下面的程式碼片段中,底層 DOM 元素將被定位兩次。

var locator = page.GetByText("Submit");
await locator.HoverAsync();
await locator.ClickAsync();