feat: add threshold to Page.isIntersectingViewport (#6497)

This commit is contained in:
Ron0115 2021-09-16 04:56:50 +08:00 committed by GitHub
parent 9399c9786f
commit 54c4318016
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 15 deletions

View File

@ -322,7 +322,7 @@
* [elementHandle.getProperties()](#elementhandlegetproperties)
* [elementHandle.getProperty(propertyName)](#elementhandlegetpropertypropertyname)
* [elementHandle.hover()](#elementhandlehover)
* [elementHandle.isIntersectingViewport()](#elementhandleisintersectingviewport)
* [elementHandle.isIntersectingViewport([options])](#elementhandleisintersectingviewportoptions)
* [elementHandle.jsonValue()](#elementhandlejsonvalue)
* [elementHandle.press(key[, options])](#elementhandlepresskey-options)
* [elementHandle.screenshot([options])](#elementhandlescreenshotoptions)
@ -4574,8 +4574,9 @@ Fetches a single property from the objectHandle.
This method scrolls element into view if needed, and then uses [page.mouse](#pagemouse) to hover over the center of the element.
If the element is detached from DOM, the method throws an error.
#### elementHandle.isIntersectingViewport()
#### elementHandle.isIntersectingViewport([options])
- `options` <[Object]>
- `threshold` <[number]> threshold for the intersection between 0 (no intersection) and 1 (full intersection). Defaults to 1.
- returns: <[Promise]<[boolean]>> Resolves to true if the element is visible in the current viewport.
#### elementHandle.jsonValue()

View File

@ -994,19 +994,20 @@ export class ElementHandle<
/**
* Resolves to true if the element is visible in the current viewport.
*/
async isIntersectingViewport(): Promise<boolean> {
return await this.evaluate<(element: Element) => Promise<boolean>>(
async (element) => {
const visibleRatio = await new Promise((resolve) => {
const observer = new IntersectionObserver((entries) => {
resolve(entries[0].intersectionRatio);
observer.disconnect();
});
observer.observe(element);
async isIntersectingViewport(options?: {
threshold?: number;
}): Promise<boolean> {
const { threshold = 0 } = options || {};
return await this.evaluate(async (element: Element, threshold: number) => {
const visibleRatio = await new Promise<number>((resolve) => {
const observer = new IntersectionObserver((entries) => {
resolve(entries[0].intersectionRatio);
observer.disconnect();
});
return visibleRatio > 0;
}
);
observer.observe(element);
});
return threshold === 1 ? visibleRatio === 1 : visibleRatio > threshold;
}, threshold);
}
}

View File

@ -17,6 +17,7 @@
#btn8 { right: -80px; top: 200px; }
#btn9 { right: -90px; top: 225px; }
#btn10 { right: -100px; top: 250px; }
#btn11 { right: -99.999px; top: 275px; }
</style>
<button id=btn0>0</button>
<button id=btn1>1</button>
@ -29,6 +30,7 @@
<button id=btn8>8</button>
<button id=btn9>9</button>
<button id=btn10>10</button>
<button id=btn11>11</button>
<script>
for (const button of document.querySelectorAll('button')) {
button.addEventListener('click', () => {

View File

@ -282,6 +282,32 @@ describe('ElementHandle specs', function () {
expect(await button.isIntersectingViewport()).toBe(visible);
}
});
it('should work with threshold', async () => {
const { page, server } = getTestState();
await page.goto(server.PREFIX + '/offscreenbuttons.html');
// a button almost cannot be seen
// sometimes we expect to return false by isIntersectingViewport1
const button = await page.$('#btn11');
expect(
await button.isIntersectingViewport({
threshold: 0.001,
})
).toBe(false);
});
it('should work with threshold of 1', async () => {
const { page, server } = getTestState();
await page.goto(server.PREFIX + '/offscreenbuttons.html');
// a button almost cannot be seen
// sometimes we expect to return false by isIntersectingViewport1
const button = await page.$('#btn0');
expect(
await button.isIntersectingViewport({
threshold: 1,
})
).toBe(true);
});
});
describe('Custom queries', function () {