德尔福的铬。如何访问DOM

时间:2017-02-27 21:41:05

标签: delphi dom chromium-embedded cef4delphi

我正在使用CEF4Delphi项目。

我的目标是加载页面并查询DOM

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

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

但是,即使我使用Chromium1.LoadURL(URL)加载页面,也永远不会调用OnDocumentAvailable

在Chromium组件加载URL后,如何才能获得对DOM的访问权限?

2 个答案:

答案 0 :(得分:2)

下载最新版本的CEF4Delphi。它拥有访问DOM的所有必要条件。

查看MiniBrowser.dpr文件中的DOMVisitor_OnDocAvailable函数(MiniBrowser演示)。

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

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

答案 1 :(得分:1)

我没有使用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处理代码不会在您的主线程中执行,您需要在编码时考虑到这一点。

祝你好运。