【问题标题】:Get Javascript reference to element with only backendNodeId from Devtools protocol仅从 Devtools 协议获取对元素的 Javascript 引用 backendNodeId
【发布时间】:2020-07-10 08:54:57
【问题描述】:

我希望能够将鼠标悬停在页面上,让它突出显示光标下方的元素(与开发人员工具检查器的方式相同),并且当我单击鼠标时获取元素的 XPath。 启用元素检查器并通过代码接收 XPath,并由人工选择元素。

我可以通过使用Chrome Devtools Protocol 和使用Overlay.setInspectMethod 和inspectNode=searchForNode 来启用开发工具检查器行为。

单击鼠标后,我会从 Overlay.inspectNodeRequested 事件中收到被单击元素的 DOM.BackendNodeId

devtools 协议似乎没有任何内置方法来获取 XPath。 所以我找到了this Chrome 开发者工具 Copy->Xpath 功能的 javascript 实现。

虽然我可以通过 CDT 协议评估 javascript,但经过数小时的尝试,当我只有 BackendNodeId 时,我无法弄清楚如何获取对节点的引用以执行 javascript 函数。

有没有办法在 javascript 中获取对节点的引用,或者有没有办法在 CDTProtocol 中获取节点 XPath?

【问题讨论】:

  • 使用 DOM.describeNode 遍历 DOM 层次结构,并在向上构建 xpath。
  • 确实想到了,这似乎是一种非常低效的解决问题的方法。希望有一个更清洁的解决方案。
  • 我不明白什么是低效的。无论如何,您都需要遍历层次结构,因此唯一添加的步骤是命令调用。您可以使用 promisify 调用和await 来获得更简洁的代码。
  • 我假设通过 CDT 协议(通过与浏览器的套接字连接)遍历 DOM 会比在浏览器中直接通过 JS 遍历 DOM 慢。我没有评估性能差异,只是假设。您是否正在考虑以另一种方式使用 DOM.describeNode ?
  • 只有一种方法可以使用 DOM.describeNode AFAICT。确实,如果您需要拨打 100 次电话,那么我猜您可能会看到不同,但通常不必担心。它也是安全的,不像在 JS 上下文中运行,站点可以重新定义/扩展一些本机类型/原型。

标签: javascript xpath google-chrome-devtools chrome-devtools-protocol


【解决方案1】:

找到合适的解决方案

首先我需要通过

获取对 Javascript 对象的引用

DOM.resolveNode, {backendNodeId: nId}

然后从返回的 JSON 对象中提取 objectId。看起来像

然后我可以调用任何我喜欢的函数,以元素为上下文

Runtime.callFunctionOn, {functionDeclaration: "function(){getXPathForElement(this)}", objectId: "{"injectedScriptId":3,"id":3}"

【讨论】:

  • 伟大的发现。你是如何让Runtime.callFunctionOn 工作的?如果我在我的 objectId 上运行你的代码片段,我会得到一个 ReferenceError: getXPathForElement is not defined↵… 你是如何在运行时上下文中声明 getXPathForElement 的?
  • 对于我的测试,我使用了来自 gist.github.com/yakimchuk/49d3c595b07c438585ccecffde3c561d 的 getXpathForElement 函数。然后我使用 Puppeteer 页面对象的 EvaluateExpression 函数将其加载到运行时 ctx 中。 HTH
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多