在评估方法之外处理人偶的页面上下文中的事件

时间:2018-07-04 21:35:32

标签: javascript node.js puppeteer

我的目标是在节点js环境中将puppeteer-chromium实例作为子进程打开,并以使用户可以从父进程访问这些事件的方式来监听用户将进行的所有单击。因此,我认为需要事件流,但是我不知道如何从评估方法发送事件(在这种情况下无法访问过程对象-铬的日志中“过程未定义”)。

当前,我正在尝试在页面上下文中添加点击侦听器,但是有什么方法可以在评估方法之外获取这些事件?

我知道评价方法可以返回promise,但这只是一个值,所以还不够。我想收集所有点击,直到我关闭铬窗口。

预先感谢所有建议。

我的示例代码:

  // parent.js
  const child = require('child_process');
  const childprocess = child.fork('./childprocess.js');
  childprocess.on('message', (msg) => {
      console.log('Message from child', msg);
      // here I'd like to get click events from childprocess
      // eg. saving them in database
  });

  // childprocess.js
  const puppeteer = require('puppeteer');
  (async () => {
      await process.on('message', (m) => {
        process.send(m)
      })
      const browser = await puppeteer.launch(options);
      const page = await browser.newPage();
      await page.goto('http://someurl.com');
      await page.evaluate( (processHandle) => {
        document.addEventListener('click', (event) => {
          console.log(event);  // event is logged in chromium dev console
          processHandle.send({msg: event}); // nothing happens
        })
      }, process);
  })()

1 个答案:

答案 0 :(得分:1)

示例代码的问题在于,processHandle不会以文档上下文中的JavaScript可以使用的方式进行序列化。您可以改为expose a function on window来完成您想要的事情:

await page.exposeFunction("sendEventToProcessHandle", (event) => {
    processHandle.send({ msg: JSON.parse(event) });
})

await page.evaluate((processHandle) => {
    document.addEventListener('click', function (e) {
        window.sendEventToProcessHandle(JSON.stringify(e));
    });
}, process)

此处,window.sendEventToProcessHandle是将在Node.JS进程的上下文中运行的函数,您可以在其中访问processHandle,但可以由文档调用。