我正在使用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的访问权限?
答案 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处理代码不会在您的主线程中执行,您需要在编码时考虑到这一点。
祝你好运。