是否可以在 Puppeteer 中使用 waitForFunction 等待按键?

Is it possible to wait for a keypress using waitForFunction in Puppeteer?

我正在尝试等待按键,而不是超时或导航。我认为 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;
        }
      });


如何让我的人偶脚本等到我按 enter 继续?

主要问题是let breakout = 0;定义了一个非全局变量。如果删除 let,您将获得一个附加到 window 对象的全局变量,即 window.breakout = 0;,它对您的 waitForFunction 回调可见。您可以通过在浏览器的控制台中键入变量名称来调试它,以查看它是否存在,而您的脚本是 运行——如果不存在,则存在范围问题,浏览器上下文中的未来评估将看不到定义。

还有一些拼写错误:您的第一个示例的谓词是 breakout == 1 但 keydown 处理程序从未将 breakout 设置为 1,它只是将其重置为 0。在第二个处理程序中,breakout = 1 是条件 if (breakout) 的默认值,1 被视为真值,给出误报。我建议使用布尔值 falsetrue 并避免 === 依赖 enterPressed 的隐式真实性(比 breakout 更清晰的名称,而不是 1 和 0 ).如果您需要使用 ==,请首选 ===,这样就不会执行不可预测的类型强制转换。

const puppeteer = require("puppeteer");

(async () => {
  const 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;
        console.log("[browser] enter was pressed");
      }
    });
  });
  await page.goto("about:blank");

  try {
    await page.waitForFunction("enterPressed");
    console.log("[node/puppeteer] enter was pressed!");
  }
  catch (err) {
    console.error("[node/puppeteer] enter was not pressed within the specified timeout");
  }

  await browser.close();
})();