Javascript 木偶演员:如何聆听对象事件

Javascript 木偶演员:如何聆听对象事件,javascript,google-chrome,headless,puppeteer,Javascript,Google Chrome,Headless,Puppeteer,是否可以侦听由页内对象调度的事件?假设我在进入的页面中有以下代码: var event = new CustomEvent('status', { detail: 'ok' }); window.addEventListener('status', function(e) { console.log('status: ', e.detail); }); setInterval(window.dispatchEvent, 1000, event); 我希望能够监听窗口对象(或任何其他JS对象

是否可以侦听由页内对象调度的事件?假设我在进入的页面中有以下代码:

var event = new CustomEvent('status', { detail: 'ok' });
window.addEventListener('status', function(e) {
  console.log('status: ', e.detail);
});
setInterval(window.dispatchEvent, 1000, event);

我希望能够监听窗口对象(或任何其他JS对象)发送的事件。如何在Puppeter中执行此操作?

首先,您必须公开一个可以从页面内调用的函数。其次,侦听事件并调用公开的函数并传递事件数据

//向页面公开处理程序
等待page.exposeFunction('onCustomEvent',({type,detail})=>{
log(`Event-fired:${type},detail:${detail}`);
});
//侦听“状态”类型的事件,并
//将“type”和“detail”属性传递给我们公开的函数
等待页面。评估onnewdocument(()=>{
addEventListener('status',({type,detail})=>{
onCustomEvent({type,detail});
});
});
等待page.goto(/*…*/);
如果页面中现在触发了一个事件
status
事件(就像您所给出的代码一样),您会看到它已登录到Node.js应用程序的控制台中


如评论中所述,可以在中找到更复杂的示例。

如果您想实际等待自定义事件,可以这样做

const page = await browser.newPage();

/**
  * Attach an event listener to page to capture a custom event on page load/navigation.
  * @param {string} type Event name.
  * @return {!Promise}
  */
function addListener(type) {
  return page.evaluateOnNewDocument(type => {
    // here we are in the browser context
    document.addEventListener(type, e => {
      window.onCustomEvent({ type, detail: e.detail });
    });
  }, type);
}

const evt = await new Promise(async resolve => {
  // Define a window.onCustomEvent function on the page.
  await page.exposeFunction('onCustomEvent', e => {
    // here we are in the node context
    resolve(e); // resolve the outer Promise here so we can await it outside
  });
  await addListener('status'); // setup listener for "status" custom event on page load
  await page.goto('http://example.com');  // N.B! Do not use { waitUntil: 'networkidle0' } as that may cause a race condition
});

console.log(`${evt.type} fired`, evt.detail || '');

基于

的示例,一个更简单的方法
wait waitForEvent('event-name',10)

/**
*等待浏览器触发事件(包括自定义事件)
*@param{string}eventName-事件名称
*@param{integer}seconds-等待的秒数。
*@returns{Promise}在触发事件或达到超时时解析
*/
异步函数waitForEvent(事件名称,秒){
秒=秒| | 30;
//使用race实现超时
回报,回报([
//添加事件侦听器并等待事件在返回前激发
page.evaluate(函数(eventName){
返回新承诺(功能(解决、拒绝){
document.addEventListener(事件名称,函数(e){
resolve();//在事件激发时解析
});
});
},事件名称),
//如果事件在n秒内未触发,则退出
page.waitForTimeout(秒*1000)
]);
}

回购协议中有一个收听自定义事件的示例:谢谢!这正是我所需要的。IMOFYI
waitFor的最佳答案已被弃用,将在未来的版本中删除。看见https://github.com/puppeteer/puppeteer/issues/6214 有关详细信息以及如何迁移代码。
已更新,谢谢@johnboilesh如何使用它?我在做:``等待page.goto(');等待waitForEvent('myCustomEvent');`我可以添加一个自定义事件处理程序,看到我的事件肯定会被触发,但这个承诺永远不会解决。不过,我使用的是
窗口。dispatchEvent
触发我的事件,而不是
文档。dispatchEvent
您好。按照这里介绍的简单方法,我在冗长的页面渲染结束时调用静态html:var event=new event(“scenerady”);窗口。dispatchEvent(事件);但是事件监听器永远不会到达NodeJS代码对应的地方。