如何为Puppeteer的ElementHandle对象设置样式?(DOM操作)
问题:通过Puppeteer的ElementHandle批量修改元素可见性
我想要修改当前页面中所有类名为something的元素的可见性,先通过以下代码获取了元素:
const manyThings = await page.$$('.something');
manyThings是包含所有匹配元素的ElementHandle对象引用数组,我想直接用这个数组批量设置元素样式——先把所有元素的visibility设为none,之后再逐个恢复可见性执行操作,操作完再隐藏。
我搜过相关方案,要么是用page.evaluate(() => document.query)重新遍历页面(不想这么做,用已有的ElementHandle应该更快),要么是找到的方案无效。尝试了下面的代码,但出现el未定义的问题:
for (let i = 0; i < manyThings.length; i++) { await manyThings[i].evaluate(function (el) { el.style.visibility = 'none'; // 尝试修改所有元素可见性,但el未定义? }.call(this)); } // 逐个设置可见 for (let i = 0; i < manyThings.length; i++) { await manyThings[i].evaluate(function (el) {el.style.visibility = ''}); // 执行操作... await manyThings[i].evaluate(function (el) {el.style.visibility = 'none'}); }
首次循环中打印manyThings[i]和el时控制台显示“undefined”错误。
解决方法
问题出在ElementHandle.evaluate()的用法上:调用单个ElementHandle的evaluate()时,回调函数的第一个参数会自动绑定当前元素,不需要额外传参,也不能用.call(this)(会覆盖默认参数绑定)。另外注意visibility的有效值是hidden,不是你写的none(none是display的属性值)。
修正后的批量隐藏代码
for (const elHandle of manyThings) { await elHandle.evaluate(el => { el.style.visibility = 'hidden'; }); }
逐个恢复、操作、再隐藏的代码
for (const elHandle of manyThings) { // 恢复可见性 await elHandle.evaluate(el => { el.style.visibility = 'visible'; }); // 执行你的操作(示例:点击元素) await elHandle.click(); // 再次隐藏元素 await elHandle.evaluate(el => { el.style.visibility = 'hidden'; }); }
额外优化
如果想减少IPC通信次数、提升批量处理效率,可以把整个ElementHandle数组传给page.evaluate(),一次性处理所有元素:
// 批量隐藏所有元素 await page.evaluate((elements) => { elements.forEach(el => { el.style.visibility = 'hidden'; }); }, manyThings);
内容的提问来源于stack exchange,提问作者DatGameh
相关产品推荐
相关产品推荐

