Chrome DevTools协议:如何获取节点的单击事件处理程序名称 [英] Chrome DevTools Protocol: How to get click event handler name of a Node
问题描述
问题
我有一个列表,列出了具有相同处理程序或功能的相同节点.
I have a list of the same nodes that has the same handler or function attached to it.
我需要单击DOM中存在的每个交互式节点(这是功能或要求).
I need to click each and every interactive node present in the DOM (this is the functionality or requirement).
如果要单击的节点已经被单击或者该节点具有相同的处理程序,我想跳过要单击的节点.
请在屏幕截图下方找到参考.在事件侦听器中,单击事件带有附加的处理程序名称.我们可以获取点击处理程序或函数的名称吗?
Please find below the screenshot for the reference. In which the event listener has a click event with the handler name attached to it. Can we get the name of the click handler or function?
我正在使用 DOMDebugger.getEventListeners({objectId:remoteObjectId})
,但不会返回 handler和originalHandler
,这不是为什么.
I am using DOMDebugger.getEventListeners({ objectId: remoteObjectId })
but it will not returning the handler and originalHandler
don't why.
推荐答案
There is a quirk mentioned here: you need objectGroup
set to get the handler. Here are some ways to get the name:
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}'
}
这篇关于Chrome DevTools协议:如何获取节点的单击事件处理程序名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!