我希望检查DOM元素是否可见Puppeteer和纯JavaScript(不是jQuery),我该怎么做?通过可见我的意思是元素通过CSS显示,而不是隐藏(f.ex. by display: none
)。
例如,我可以通过以下方式确定我的元素#menu
是否未通过CSS规则display: none
隐藏:
const isNotHidden = await page.$eval('#menu', (elem) => {
return elem.style.display !== 'none'
})
我如何确定该元素是否隐藏,而不仅仅是display: none
?
答案 0 :(得分:16)
我发现Puppeteer有一个用于此目的的API方法:Page.waitForSelector,通过其visible
选项。我不知道后一个选项,但它让你等到元素可见。
await page.waitForSelector('#element', {
visible: true,
})
相反,您可以通过hidden
选项等待隐藏元素。
对于Puppeteer API,我认为这是惯用的答案。感谢Colin Cline,因为我认为他的答案可能是一般的JavaScript解决方案。
答案 1 :(得分:6)
使用boundingBox()
此方法返回元素的边界框(相对于主框架);如果该元素不可见,则返回null。
API:https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#elementhandleboundingbox
答案 2 :(得分:4)
当前接受的答案包括等待,以使元素显示并可见。
如果我们对等待元素不感兴趣,而只是想测试元素的可见性,则可以结合使用getComputedStyle()
和getBoundingClientRect()
来测试元素是否可见。元素可见。
我们可以首先检查visibility
是否未设置为hidden
。
然后我们可以通过检查bottom
,top
,height
和width
属性是否未设置为{{1}来验证边界框是否可见}(这也会过滤将display
设置为0
的元素。)
none
答案 3 :(得分:2)
一个是通过检查其显示样式值。
第二个是通过检查它的高度,对于exp,如果元素是offsetHeight
元素的子元素,0
将是opacity: 0
,因此你知道尽管显示值很大,但该元素仍然不可见。 const isNotHidden = await page.$eval('#menu', (elem) => {
return window.getComputedStyle(elem).getPropertyValue('display') !== 'none' && elem.offsetHeight
});
不被视为隐藏元素,因此我们不会检查它。
elem.offsetWidth
你也可以检查<div id=<%# Eval("UnitName") %>>
并且在进行任何计算之前都没有坏,检查元素是否存在。
答案 4 :(得分:0)
显然,这是jQuery的工作方式:
visible = await page.evaluate((e) => e.offsetWidth > 0 && e.offsetHeight > 0, element)
答案 5 :(得分:0)
如果只想知道某个元素是否可见,则可以使用此功能。在调用此函数之前,应确保页面已准备就绪。您可以通过在希望显示的其他元素上使用waitForSelector来做到这一点。
async function isVisible(page, selector) {
return await page.evaluate((selector) => {
var e = document.querySelector(selector);
if (e) {
var style = window.getComputedStyle(e);
return style && style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0';
}
else {
return false;
}
}, selector);
}
// Example usage:
page.waitForSelector('#otherPeerElement');
var myElementIsVisible = await isVisible(page, '#visibleOrNot');
if (myElementIsVisible) {
// Interact with #visibleOrNot
}
答案 6 :(得分:0)
此代码绝对可以帮助您。 基本上,这意味着该元素已经在页面上可用,但尚不可见,或者在CSS中不可见,显示属性设置为none或可见性被隐藏。现在,在编写测试时,我们假设一旦元素可用,就对其进行操作,例如单击或键入。但是由于此元素尚不可见,Puppeteer无法执行该操作。
async function isLocatorReady(element, page) {
const isVisibleHandle = await page.evaluateHandle((e) =>
{
const style = window.getComputedStyle(e);
return (style && style.display !== 'none' &&
style.visibility !== 'hidden' && style.opacity !== '0');
}, element);
var visible = await isVisibleHandle.jsonValue();
const box = await element.boxModel();
if (visible && box) {
return true;
}
return false;
}
答案 7 :(得分:0)
pandas.Series.str.extract
答案 8 :(得分:0)
也许您可以使用elementHandle.boundingBox()
(感谢@huypham的想法)
它将返回一个Promise,它显示元素的边框(相对于主框架);如果元素不可见,则返回null。
代码段示例:
const loadMoreButton = await getDataPage.$(
'button.ao-tour-reviews__load-more-cta.js-ao-tour-reviews__load-more-cta'
);
const buttonVisible = await loadMoreButton.boundingBox();
if (buttonVisible) {
await loadMoreButton.click().catch((e) => {
console.log('???: ' + e)
});
}
答案 9 :(得分:0)
根据剧作家的逻辑检查元素是否可见-https://github.com/microsoft/playwright/blob/master/src/server/injected/injectedScript.ts#L120-L129
function isVisible(element: Element): boolean {
// Note: this logic should be similar to waitForDisplayedAtStablePosition() to avoid surprises.
if (!element.ownerDocument || !element.ownerDocument.defaultView)
return true;
const style = element.ownerDocument.defaultView.getComputedStyle(element);
if (!style || style.visibility === 'hidden')
return false;
const rect = element.getBoundingClientRect();
return rect.width > 0 && rect.height > 0;
}
答案 10 :(得分:-1)
我会使用@ aknuds1的方法,但是您也可以执行以下操作。
expect((await page.$('#element')) !== null).toEqual(true)
如果您异步获取资源,请注意上述期望可能不会通过,因为它不会等待更改反映在UI上。这就是在这种情况下可能不推荐使用这种方法的原因。