0
# Element Handling
1
2
Direct element manipulation through ElementHandle for precise control over DOM elements with property access, interaction methods, and visual feedback.
3
4
## Capabilities
5
6
### ElementHandle Class
7
8
Handle to a DOM element providing direct access to element properties and methods.
9
10
```typescript { .api }
11
/**
12
* Handle to a DOM element in the page
13
* Extends JSHandle with element-specific functionality
14
*/
15
class ElementHandle extends JSHandle<Element> {
16
/**
17
* Find child element matching selector
18
* @param selector - CSS selector
19
* @returns Promise resolving to ElementHandle or null
20
*/
21
$(selector: string): Promise<ElementHandle | null>;
22
23
/**
24
* Find all child elements matching selector
25
* @param selector - CSS selector
26
* @returns Promise resolving to array of ElementHandles
27
*/
28
$$(selector: string): Promise<ElementHandle[]>;
29
30
/**
31
* Evaluate function on child element
32
* @param selector - CSS selector
33
* @param pageFunction - Function to evaluate
34
* @param args - Arguments to pass to function
35
* @returns Promise resolving to function result
36
*/
37
$eval<R>(
38
selector: string,
39
pageFunction: (element: Element, ...args: any[]) => R,
40
...args: any[]
41
): Promise<R>;
42
43
/**
44
* Evaluate function on all child elements
45
* @param selector - CSS selector
46
* @param pageFunction - Function to evaluate
47
* @param args - Arguments to pass to function
48
* @returns Promise resolving to function result
49
*/
50
$$eval<R>(
51
selector: string,
52
pageFunction: (elements: Element[], ...args: any[]) => R,
53
...args: any[]
54
): Promise<R>;
55
}
56
```
57
58
### Element Interaction
59
60
User interaction methods for clicking, typing, and form manipulation.
61
62
```typescript { .api }
63
/**
64
* Click the element
65
* @param options - Click options
66
* @returns Promise that resolves when click completes
67
*/
68
click(options?: ClickOptions): Promise<void>;
69
70
/**
71
* Focus the element
72
* @returns Promise that resolves when focus completes
73
*/
74
focus(): Promise<void>;
75
76
/**
77
* Hover over the element
78
* @returns Promise that resolves when hover completes
79
*/
80
hover(): Promise<void>;
81
82
/**
83
* Tap the element (touch interaction)
84
* @returns Promise that resolves when tap completes
85
*/
86
tap(): Promise<void>;
87
88
/**
89
* Type text into the element
90
* @param text - Text to type
91
* @param options - Typing options
92
* @returns Promise that resolves when typing completes
93
*/
94
type(text: string, options?: TypeOptions): Promise<void>;
95
96
/**
97
* Press a key while element is focused
98
* @param key - Key to press
99
* @param options - Press options
100
* @returns Promise that resolves when key press completes
101
*/
102
press(key: KeyInput, options?: PressOptions): Promise<void>;
103
104
/**
105
* Select options in select element
106
* @param values - Option values to select
107
* @returns Promise resolving to selected values
108
*/
109
select(...values: string[]): Promise<string[]>;
110
111
interface ClickOptions {
112
/** Mouse button to use */
113
button?: "left" | "right" | "middle";
114
/** Number of clicks */
115
clickCount?: number;
116
/** Delay between mousedown and mouseup */
117
delay?: number;
118
/** Offset from element center */
119
offset?: {x: number; y: number};
120
}
121
122
interface TypeOptions {
123
/** Delay between key presses */
124
delay?: number;
125
}
126
127
interface PressOptions {
128
/** Delay before releasing key */
129
delay?: number;
130
/** Text to insert (for printable keys) */
131
text?: string;
132
}
133
```
134
135
**Usage Examples:**
136
137
```typescript
138
// Get element handle
139
const button = await page.$("#submit-button");
140
141
if (button) {
142
// Click element
143
await button.click();
144
145
// Click with options
146
await button.click({
147
button: "right", // Right click
148
clickCount: 2, // Double click
149
delay: 100 // 100ms between mousedown/mouseup
150
});
151
}
152
153
// Type into input field
154
const input = await page.$("#email");
155
if (input) {
156
await input.focus();
157
await input.type("user@example.com", { delay: 50 });
158
await input.press("Enter");
159
}
160
161
// Select dropdown options
162
const select = await page.$("#country");
163
if (select) {
164
await select.select("US", "CA"); // Multi-select
165
}
166
```
167
168
### Drag and Drop Operations
169
170
Comprehensive drag and drop functionality for complex interactions.
171
172
```typescript { .api }
173
/**
174
* Start drag operation from element
175
* @param target - Target coordinates
176
* @returns Promise resolving to drag data
177
*/
178
drag(target: Point): Promise<Protocol.Input.DragData>;
179
180
/**
181
* Trigger drag enter event
182
* @param data - Drag data from drag operation
183
* @returns Promise that resolves when drag enter completes
184
*/
185
dragEnter(data?: Protocol.Input.DragData): Promise<void>;
186
187
/**
188
* Trigger drag over event
189
* @param data - Drag data from drag operation
190
* @returns Promise that resolves when drag over completes
191
*/
192
dragOver(data?: Protocol.Input.DragData): Promise<void>;
193
194
/**
195
* Trigger drop event
196
* @param data - Drag data from drag operation
197
* @returns Promise that resolves when drop completes
198
*/
199
drop(data?: Protocol.Input.DragData): Promise<void>;
200
201
/**
202
* Drag element to target element
203
* @param target - Target element to drop on
204
* @param options - Drag options
205
* @returns Promise that resolves when drag and drop completes
206
*/
207
dragAndDrop(
208
target: ElementHandle,
209
options?: {delay?: number}
210
): Promise<void>;
211
212
interface Point {
213
x: number;
214
y: number;
215
}
216
```
217
218
**Usage Examples:**
219
220
```typescript
221
// Simple drag and drop between elements
222
const source = await page.$("#draggable");
223
const target = await page.$("#dropzone");
224
225
if (source && target) {
226
await source.dragAndDrop(target);
227
}
228
229
// Manual drag and drop with custom control
230
const dragHandle = await page.$("#drag-handle");
231
if (dragHandle) {
232
// Start drag
233
const dragData = await dragHandle.drag({ x: 100, y: 100 });
234
235
// Simulate drag over target
236
const dropTarget = await page.$("#drop-target");
237
if (dropTarget) {
238
await dropTarget.dragOver(dragData);
239
await dropTarget.drop(dragData);
240
}
241
}
242
```
243
244
### Touch Events
245
246
Touch-specific interactions for mobile and tablet interfaces.
247
248
```typescript { .api }
249
/**
250
* Start touch interaction
251
* @returns Promise resolving to TouchHandle
252
*/
253
touchStart(): Promise<TouchHandle>;
254
255
/**
256
* Move touch to coordinates
257
* @param target - Target coordinates
258
* @returns Promise that resolves when touch move completes
259
*/
260
touchMove(target: Point): Promise<void>;
261
262
/**
263
* End touch interaction
264
* @returns Promise that resolves when touch end completes
265
*/
266
touchEnd(): Promise<void>;
267
268
interface TouchHandle {
269
/** Move touch to new coordinates */
270
move(point: Point): Promise<void>;
271
/** End the touch */
272
end(): Promise<void>;
273
}
274
```
275
276
**Usage Examples:**
277
278
```typescript
279
// Touch interactions for mobile
280
const touchElement = await page.$("#mobile-button");
281
if (touchElement) {
282
// Simple tap
283
await touchElement.tap();
284
285
// Complex touch gestures
286
const touch = await touchElement.touchStart();
287
await touch.move({ x: 100, y: 0 }); // Swipe right
288
await touch.end();
289
}
290
```
291
292
### Element Properties and State
293
294
Access element dimensions, visibility, and layout information.
295
296
```typescript { .api }
297
/**
298
* Get element bounding box
299
* @returns Promise resolving to bounding box or null if not visible
300
*/
301
boundingBox(): Promise<BoundingBox | null>;
302
303
/**
304
* Get element box model (including padding, border, margin)
305
* @returns Promise resolving to box model or null
306
*/
307
boxModel(): Promise<BoxModel | null>;
308
309
/**
310
* Get content frame for iframe elements
311
* @returns Promise resolving to Frame or null
312
*/
313
contentFrame(): Promise<Frame | null>;
314
315
/**
316
* Check if element is visible
317
* @returns Promise resolving to true if visible
318
*/
319
isVisible(): Promise<boolean>;
320
321
/**
322
* Check if element is hidden
323
* @returns Promise resolving to true if hidden
324
*/
325
isHidden(): Promise<boolean>;
326
327
/**
328
* Check if element intersects with viewport
329
* @param options - Intersection options
330
* @returns Promise resolving to true if intersecting
331
*/
332
isIntersectingViewport(options?: {threshold?: number}): Promise<boolean>;
333
334
interface BoundingBox {
335
/** X coordinate of top-left corner */
336
x: number;
337
/** Y coordinate of top-left corner */
338
y: number;
339
/** Width of element */
340
width: number;
341
/** Height of element */
342
height: number;
343
}
344
345
interface BoxModel {
346
/** Content box */
347
content: Quad;
348
/** Padding box */
349
padding: Quad;
350
/** Border box */
351
border: Quad;
352
/** Margin box */
353
margin: Quad;
354
/** Element width */
355
width: number;
356
/** Element height */
357
height: number;
358
}
359
360
interface Quad {
361
/** Array of 8 numbers representing 4 points (x1,y1,x2,y2,x3,y3,x4,y4) */
362
quad: number[];
363
}
364
```
365
366
**Usage Examples:**
367
368
```typescript
369
const element = await page.$("#content");
370
371
if (element) {
372
// Get element dimensions
373
const box = await element.boundingBox();
374
if (box) {
375
console.log(`Element is ${box.width}x${box.height} at (${box.x}, ${box.y})`);
376
}
377
378
// Check visibility
379
const isVisible = await element.isVisible();
380
const isHidden = await element.isHidden();
381
382
console.log(`Visible: ${isVisible}, Hidden: ${isHidden}`);
383
384
// Check if in viewport
385
const inViewport = await element.isIntersectingViewport();
386
const partiallyVisible = await element.isIntersectingViewport({ threshold: 0.5 });
387
388
// Get detailed box model
389
const boxModel = await element.boxModel();
390
if (boxModel) {
391
console.log(`Content: ${boxModel.width}x${boxModel.height}`);
392
}
393
}
394
395
// Handle iframe content
396
const iframe = await page.$("iframe");
397
if (iframe) {
398
const frame = await iframe.contentFrame();
399
if (frame) {
400
// Interact with iframe content
401
await frame.click("#button-in-iframe");
402
}
403
}
404
```
405
406
### Screenshots
407
408
Capture visual representations of specific elements.
409
410
```typescript { .api }
411
/**
412
* Take screenshot of element
413
* @param options - Screenshot options
414
* @returns Promise resolving to image buffer
415
*/
416
screenshot(options?: ScreenshotOptions): Promise<Uint8Array>;
417
418
interface ScreenshotOptions {
419
/** Path to save screenshot */
420
path?: string;
421
/** Image type */
422
type?: "png" | "jpeg" | "webp";
423
/** Image quality (0-100, JPEG only) */
424
quality?: number;
425
/** Omit background (PNG only) */
426
omitBackground?: boolean;
427
/** Capture beyond device screen size */
428
captureBeyondViewport?: boolean;
429
/** Encoding format */
430
encoding?: "base64" | "binary";
431
}
432
```
433
434
**Usage Examples:**
435
436
```typescript
437
const element = await page.$("#chart");
438
439
if (element) {
440
// Take PNG screenshot
441
const buffer = await element.screenshot();
442
443
// Save to file with options
444
await element.screenshot({
445
path: "element.png",
446
type: "png",
447
omitBackground: true
448
});
449
450
// Get base64 encoded image
451
const base64 = await element.screenshot({
452
encoding: "base64",
453
type: "jpeg",
454
quality: 80
455
});
456
}
457
```
458
459
### Scrolling Operations
460
461
Control element scrolling and viewport positioning.
462
463
```typescript { .api }
464
/**
465
* Scroll element into view
466
* @returns Promise that resolves when scrolling completes
467
*/
468
scrollIntoView(): Promise<void>;
469
```
470
471
**Usage Examples:**
472
473
```typescript
474
const element = await page.$("#footer-content");
475
476
if (element) {
477
// Scroll element into view
478
await element.scrollIntoView();
479
480
// Wait a moment for scroll animation
481
await page.waitForTimeout(500);
482
483
// Then interact with element
484
await element.click();
485
}
486
```
487
488
### Form Operations
489
490
Specialized form handling including autofill functionality.
491
492
```typescript { .api }
493
/**
494
* Autofill form element with provided data
495
* @param data - Autofill data
496
* @returns Promise that resolves when autofill completes
497
*/
498
autofill(data: AutofillData): Promise<void>;
499
500
interface AutofillData {
501
/** Form fields to fill */
502
fields: Array<{
503
/** Field name */
504
name: string;
505
/** Field value */
506
value: string;
507
}>;
508
}
509
```
510
511
**Usage Examples:**
512
513
```typescript
514
const form = await page.$("form");
515
516
if (form) {
517
// Autofill form
518
await form.autofill({
519
fields: [
520
{ name: "firstName", value: "John" },
521
{ name: "lastName", value: "Doe" },
522
{ name: "email", value: "john@example.com" }
523
]
524
});
525
}
526
```
527
528
### Locator Conversion
529
530
Convert ElementHandle to modern Locator API for enhanced reliability.
531
532
```typescript { .api }
533
/**
534
* Convert ElementHandle to Locator
535
* @returns Locator instance for this element
536
*/
537
asLocator(): Locator<Element>;
538
```
539
540
**Usage Examples:**
541
542
```typescript
543
const element = await page.$("#dynamic-content");
544
545
if (element) {
546
// Convert to locator for better reliability
547
const locator = element.asLocator();
548
549
// Use locator methods with automatic retries
550
await locator.click();
551
await locator.fill("new value");
552
}
553
```
554
555
### Element Disposal
556
557
Properly clean up element handles to prevent memory leaks.
558
559
```typescript { .api }
560
/**
561
* Dispose of element handle and release browser resources
562
* @returns Promise that resolves when disposal completes
563
*/
564
dispose(): Promise<void>;
565
```
566
567
**Usage Examples:**
568
569
```typescript
570
const elements = await page.$$(".temporary-elements");
571
572
// Process elements
573
for (const element of elements) {
574
const text = await element.evaluate(el => el.textContent);
575
console.log(text);
576
577
// Dispose when done
578
await element.dispose();
579
}
580
```
581
582
## JSHandle Class
583
584
Handle to JavaScript objects in the browser context, providing access to properties and evaluation capabilities.
585
586
### JavaScript Object Manipulation
587
588
Access properties and evaluate functions on JavaScript objects.
589
590
```typescript { .api }
591
/**
592
* Handle to a JavaScript object in browser context
593
*/
594
class JSHandle<T = any> {
595
/** Get property by name */
596
getProperty(propertyName: string): Promise<JSHandle>;
597
598
/** Get all properties as Map */
599
getProperties(): Promise<Map<string, JSHandle>>;
600
601
/** Evaluate function with this handle as context */
602
evaluate<R>(
603
pageFunction: (obj: T, ...args: any[]) => R,
604
...args: any[]
605
): Promise<R>;
606
607
/** Evaluate function and return handle to result */
608
evaluateHandle<R>(
609
pageFunction: (obj: T, ...args: any[]) => R,
610
...args: any[]
611
): Promise<JSHandle<R>>;
612
613
/** Get JSON representation of object */
614
jsonValue(): Promise<T>;
615
616
/** Convert to ElementHandle if object is an Element */
617
asElement(): ElementHandle | null;
618
619
/** Get string representation */
620
toString(): string;
621
622
/** Dispose handle and release browser resources */
623
dispose(): Promise<void>;
624
}
625
```
626
627
**Usage Examples:**
628
629
```typescript
630
// Get handle to window object
631
const windowHandle = await page.evaluateHandle(() => window);
632
633
// Access properties
634
const locationHandle = await windowHandle.getProperty("location");
635
const href = await locationHandle.jsonValue();
636
console.log("Current URL:", href);
637
638
// Get all properties
639
const windowProps = await windowHandle.getProperties();
640
for (const [name, handle] of windowProps) {
641
console.log(`Property: ${name}`);
642
await handle.dispose(); // Clean up
643
}
644
645
// Evaluate with handle context
646
const result = await windowHandle.evaluate((win) => {
647
return {
648
width: win.innerWidth,
649
height: win.innerHeight,
650
userAgent: win.navigator.userAgent
651
};
652
});
653
654
// Handle arrays and complex objects
655
const arrayHandle = await page.evaluateHandle(() => [1, 2, 3, 4, 5]);
656
const sum = await arrayHandle.evaluate((arr) =>
657
arr.reduce((total, num) => total + num, 0)
658
);
659
console.log("Sum:", sum); // 15
660
661
// Convert to element if possible
662
const elementHandle = await page.evaluateHandle(() => document.body);
663
const element = elementHandle.asElement();
664
if (element) {
665
await element.click();
666
}
667
668
// Clean up handles
669
await windowHandle.dispose();
670
await locationHandle.dispose();
671
await arrayHandle.dispose();
672
```