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.getProperties()](#elementhandlegetproperties)
* [elementHandle.getProperty(propertyName)](#elementhandlegetpropertypropertyname) * [elementHandle.getProperty(propertyName)](#elementhandlegetpropertypropertyname)
* [elementHandle.hover()](#elementhandlehover) * [elementHandle.hover()](#elementhandlehover)
* [elementHandle.isIntersectingViewport()](#elementhandleisintersectingviewport) * [elementHandle.isIntersectingViewport([options])](#elementhandleisintersectingviewportoptions)
* [elementHandle.jsonValue()](#elementhandlejsonvalue) * [elementHandle.jsonValue()](#elementhandlejsonvalue)
* [elementHandle.press(key[, options])](#elementhandlepresskey-options) * [elementHandle.press(key[, options])](#elementhandlepresskey-options)
* [elementHandle.screenshot([options])](#elementhandlescreenshotoptions) * [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. 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. 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. - returns: <[Promise]<[boolean]>> Resolves to true if the element is visible in the current viewport.
#### elementHandle.jsonValue() #### elementHandle.jsonValue()

View File

@ -994,19 +994,20 @@ export class ElementHandle<
/** /**
* Resolves to true if the element is visible in the current viewport. * Resolves to true if the element is visible in the current viewport.
*/ */
async isIntersectingViewport(): Promise<boolean> { async isIntersectingViewport(options?: {
return await this.evaluate<(element: Element) => Promise<boolean>>( threshold?: number;
async (element) => { }): Promise<boolean> {
const visibleRatio = await new Promise((resolve) => { const { threshold = 0 } = options || {};
const observer = new IntersectionObserver((entries) => { return await this.evaluate(async (element: Element, threshold: number) => {
resolve(entries[0].intersectionRatio); const visibleRatio = await new Promise<number>((resolve) => {
observer.disconnect(); const observer = new IntersectionObserver((entries) => {
}); resolve(entries[0].intersectionRatio);
observer.observe(element); 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; } #btn8 { right: -80px; top: 200px; }
#btn9 { right: -90px; top: 225px; } #btn9 { right: -90px; top: 225px; }
#btn10 { right: -100px; top: 250px; } #btn10 { right: -100px; top: 250px; }
#btn11 { right: -99.999px; top: 275px; }
</style> </style>
<button id=btn0>0</button> <button id=btn0>0</button>
<button id=btn1>1</button> <button id=btn1>1</button>
@ -29,6 +30,7 @@
<button id=btn8>8</button> <button id=btn8>8</button>
<button id=btn9>9</button> <button id=btn9>9</button>
<button id=btn10>10</button> <button id=btn10>10</button>
<button id=btn11>11</button>
<script> <script>
for (const button of document.querySelectorAll('button')) { for (const button of document.querySelectorAll('button')) {
button.addEventListener('click', () => { button.addEventListener('click', () => {

View File

@ -282,6 +282,32 @@ describe('ElementHandle specs', function () {
expect(await button.isIntersectingViewport()).toBe(visible); 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 () { describe('Custom queries', function () {