我正在尝试等待按键,而不是等待超时或导航。我认为使用
page.waitForFunction()
这是可能的,但我自己的实现并不成功。
我已经尝试过:
addKeydown("keydown");
function addKeydown(type) {
return page.evaluateOnNewDocument((type) => {
// here we are in the browser context
let breakout = 0;
document.addEventListener("keydown", (e) => {
if (e.code === "Enter") {
breakout = 0;
}
});
}, type);
}
await page.waitForFunction("breakout == 1");
和
await page.waitForFunction(() => {
console.log("trying function");
let breakout = 1;
let event = (ev) => {
if (ev.keyCode == "Enter") {
breakout = 0;
}
};
document.addEventListener("keydown", event);
if (breakout) {
return true;
}
});
如何让我的 puppeteer 脚本等到我按
enter
才能继续?
主要问题是
let breakout = 0;
定义了一个非全局变量。如果您删除 let
,您将获得一个附加到 window
对象的全局变量,即 window.breakout = 0;
,它对您的 waitForFunction
回调可见。您可以通过在浏览器的控制台中输入变量名称来调试它,以查看它在脚本运行时是否存在 - 如果不存在,则存在范围问题,并且浏览器上下文中的未来评估将看不到定义。
还有一些拼写错误:第一个示例的谓词是
breakout == 1
,但 keydown 处理程序从未将 breakout
设置为 1,它只是将其重置为 0。在第二个处理程序中,breakout = 1
是条件的默认值if (breakout)
,1 被视为真实,给出假阳性。我建议使用布尔值 false
和 true
而不是 1 和 0,并避免使用 ===
来依赖于 enterPressed
的隐式真实性(比 breakout
更清晰的名称)。如果您需要使用 ==
,请优先使用 ===
,这样就不会执行不可预测的类型强制。
const puppeteer = require("puppeteer"); // ^22.2.0
let browser;
(async () => {
browser = await puppeteer.launch({headless: false});
const [page] = await browser.pages();
await page.evaluateOnNewDocument(() => {
enterPressed = false;
document.addEventListener("keydown", e => {
if (e.code === "Enter") {
enterPressed = true;
}
});
});
await page.goto("about:blank");
try {
await page.waitForFunction("enterPressed");
console.log("enter was pressed!");
}
catch (err) {
console.error("enter was not pressed within the specified timeout");
}
})()
.catch(err => console.error(err))
.finally(() => browser?.close());