这里提到了一个怪癖:您需要objectGroup
设置才能获取处理程序。以下是一些获取名称的方法:
const html = `
<!doctype html>
<html>
<head>
<meta charset='UTF-8'>
<title>Test</title>
<script>
function main() {
document.body.addEventListener('click', logClick);
}
function logClick() {
console.log('click');
}
</script>
</head>
<body onload='main();'>Text.</body>
</html>`;
const puppeteer = require('puppeteer');
(async function main() {
try {
const browser = await puppeteer.launch();
const [page] = await browser.pages();
await page.goto(`data:text/html,${html}`);
const cdp = await page.target().createCDPSession();
const nodeObject = (await cdp.send('Runtime.evaluate', {
expression: "document.querySelector('body')",
objectGroup: 'foobar',
})).result;
const listenerObject = (await cdp.send('DOMDebugger.getEventListeners', {
objectId: nodeObject.objectId,
})).listeners[0].handler;
const listenerName1 = (await cdp.send('Runtime.callFunctionOn', {
functionDeclaration: 'function() { return this.name; }',
objectId: listenerObject.objectId,
returnByValue: true,
})).result.value;
const listenerName2 = (await cdp.send('Runtime.getProperties', {
objectId: listenerObject.objectId,
ownProperties: true,
})).result.find(property => property.name === 'name').value.value;
await cdp.send('Runtime.releaseObject', { objectId: listenerObject.objectId });
await cdp.send('Runtime.releaseObject', { objectId: nodeObject.objectId });
await cdp.send('Runtime.releaseObjectGroup', { objectGroup: 'foobar' });
console.log(listenerName1);
console.log(listenerName2);
await browser.close();
} catch (err) {
console.error(err);
}
})();
输出:
logClick
logClick
UPD
匿名处理程序:
const puppeteer = require('puppeteer');
(async function main() {
try {
const browser = await puppeteer.launch();
const [page] = await browser.pages();
await page.goto('https://jqueryui.com/resources/demos/datepicker/inline.html');
const cdp = await page.target().createCDPSession();
const nodeObject = (await cdp.send('Runtime.evaluate', {
expression: "document.querySelector('a.ui-datepicker-next')",
objectGroup: 'foobar',
})).result;
const listenerObject = (await cdp.send('DOMDebugger.getEventListeners', {
objectId: nodeObject.objectId,
})).listeners[0].handler;
console.log(listenerObject);
await cdp.send('Runtime.releaseObject', { objectId: listenerObject.objectId });
await cdp.send('Runtime.releaseObject', { objectId: nodeObject.objectId });
await cdp.send('Runtime.releaseObjectGroup', { objectGroup: 'foobar' });
await browser.close();
} catch (err) {
console.error(err);
}
})();
输出:
{
type: 'function',
className: 'Function',
description: 'function( e ) {\n' +
'\n' +
'\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n' +
'\t\t\t\t// when an event is called after a page has unloaded\n' +
'\t\t\t\treturn typeof jQuery !== "undefined" &&\n' +
'\t\t\t\t\t( !e || jQuery.event.triggered !== e.type ) ?\n' +
'\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n' +
'\t\t\t\t\tundefined;\n' +
'\t\t\t}',
objectId: '{"injectedScriptId":3,"id":2}'
}