【问题标题】:Chromium in Delphi. How to access DOM德尔福的铬。如何访问 DOM
【发布时间】:2017-02-27 21:41:04
【问题描述】:

我正在使用CEF4Delphi 项目。

我的目标是加载一个页面并询问 DOM

我定义了一个事件处理程序Chromium1.OnDocumentAvailable,我可以在其中做

procedure TMiniBrowserFrm.Chromium1DocumentAvailable(Sender: TObject; const aDocument: ICefDomDocument);
begin
  aDocument.GetElementById('client').ElementBounds;
end;

不过,OnDocumentAvailable 永远不会被调用,即使我使用 Chromium1.LoadURL(URL) 加载页面时也是如此。

如何在 Chromium 组件加载 URL 后访问 DOM?

【问题讨论】:

  • 听起来可能是个愚蠢的问题,但您确定已将此事件处理程序分配给该事件吗?
  • 是的,我同意,通过 DFM 和 Code 都尝试过
  • 有意思,我这里安装的Chromium版本(v3)没有这样的事件。必须是刚刚在 v4 中添加的。
  • 我正在使用 cef_binary_3.2924.1571.gcdcdfa9_windows32
  • 查看源代码,该事件是由过程DOMVisitorVisit 触发的,该过程似乎没有从任何地方调用。请记住,看起来整个项目都在积极开发中,并且几乎每天都在提交。您可能想改用 CEF3。

标签: delphi dom chromium-embedded cef4delphi


【解决方案1】:

下载最新版本的 CEF4Delphi。它拥有访问 DOM 所需的一切。

查看 uDOMVisitor.pas 文件中的 DOMVisitor_OnDocAvailable 函数(DOMVisitor 演示)。

您提到的旧事件不再存在,DOMVisitor 现在使用带有 TCefFastDomVisitor 的自定义 RenderProcessHandler。

运行 DOMVisitor 并在加载后右键单击网页,然后选择“访问 DOM”。

【讨论】:

    【解决方案2】:

    我没有使用过 CEF4,但 CEF 3 中包含的一个演示展示了如何 使用 Chromium DOM。与 TWebBrowser 不同的是,不幸的是,它不是 获取 COM 接口作为进入 DOM 解析器的一种简单方法。因此,您当前的代码不起作用的原因是您没有采取必要的步骤来使用 DOM。

    相关的 CEF3 示例是名为“Guiclient”的示例,它使用自定义 调用 DOM 处理的操作:

    procedure TMainForm.actDomExecute(Sender: TObject);
    begin
      crm.browser.SendProcessMessage(PID_RENDERER,
        TCefProcessMessageRef.New('visitdom'));
    end;
    

    如您所见,这涉及向 Chromium 的渲染过程发送消息, 并使用自定义类来处理它:

    TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn)
    protected
      procedure OnWebKitInitialized; override;
      function OnProcessMessageReceived(const browser: ICefBrowser; sourceProcess: TCefProcessId;
        const message: ICefProcessMessage): Boolean; override;
    end;
    [...]
    function TCustomRenderProcessHandler.OnProcessMessageReceived(
      const browser: ICefBrowser; sourceProcess: TCefProcessId;
      const message: ICefProcessMessage): Boolean;
    begin
    //{$IFDEF DELPHI14_UP}
      if (message.Name = 'visitdom') then
        begin
          browser.MainFrame.VisitDomProc(
            procedure(const doc: ICefDomDocument) begin
              doc.Body.AddEventListenerProc('mouseover', True,
                procedure (const event: ICefDomEvent)
                var
                  msg: ICefProcessMessage;
                begin
                  msg := TCefProcessMessageRef.New('mouseover');
                  msg.ArgumentList.SetString(0, getpath(event.Target));
                  browser.SendProcessMessage(PID_BROWSER, msg);
                end)
            end);
            Result := True;
        end
      else
    //{$ENDIF}
    //    Result := False;
    end;
    
    procedure TCustomRenderProcessHandler.OnWebKitInitialized;
    begin
    {$IFDEF DELPHI14_UP}
      TCefRTTIExtension.Register('app', TTestExtension);
    {$ENDIF}
    end;
    

    因此,与 TWebBrowser 不同的是,您的 DOM 处理代码不会在主线程中执行,您需要在编码中考虑到这一点。

    祝你好运。

    【讨论】:

    • 这对您的 q 有帮助吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多