delphi - 如何可靠地知道(以编程方式)页面何时在 Chromium 中加载

标签 delphi chromium tchromium

我在使用 TChromium (DCEF1) 的 OnLoadEnd 事件时遇到问题。

我有一个带有 TButton 和 TChromium 的表单。

按钮的 OnClick 事件调用一个列出已加载页面的表单的函数。如果我等待页面加载完成然后单击按钮,则此功能可以正常工作;但如果我从 TChromium OnLoadEnd 事件处理程序调用此函数,则永远不会调用回调函数,因此我会得到一个空列表。

按钮代码(将注释读入代码中):

procedure TForm2.Button3Click(Sender: TObject);
var
  Q: TWebChromium;
begin
  Q := TWebChromium.Create(Chromium1); // <- class to access DOM
  Q.WebFormNames; // <- method to get forms name
  ShowMessage(Q.Forms.Text); // <- show forms
end;

OnLoadEnd代码:

procedure TForm2.Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser;
  const frame: ICefFrame; httpStatusCode: Integer; out Result: Boolean);
begin
  if (browser <> nil) and (browser.GetWindowHandle = TChromium(Sender).BrowserHandle) and ((frame = nil) or (frame.IsMain)) then
  begin
    Button3Click(nil);
  end;
end;

获取表单名称的方法代码(将注释读入代码中):

procedure TWebChromium.WebFormNames;
var
  Finish: Boolean;
  EndTime: TTime;
begin
  FForms.Clear; // <- property (TStringList)
  if not Assigned(FWebBrowser) then // <- FWebBrowser: property that contain the TChromium
    raise Exception.Create('WebBrowser not assigned');
  if not (FWebBrowser is TChromium) then 
    raise Exception.Create('The WebBrowser property is not a TChromium.');

  Finish := False;
  TChromium(FWebBrowser).Browser.MainFrame.VisitDomProc(
        procedure (const doc: ICefDomDocument) // <- this procedure is not called if this method is called from OnLoadEnd event
        begin
          FForms.CommaText := GetFormsName(doc.Body); 
          Finish := True;
        end
  );
  EndTime := IncSecond(Time, 4);

  repeat Application.ProcessMessages until Finish or (Time > EndTime);
  if Time > EndTime then
    raise Exception.Create('Time out');
end;

最佳答案

嗯,我知道这个问题是几年前提出的,但我对 TChromium 还很陌生。这是我从之前的提案中提出的解决方案。一般来说,TChromium 发送事件 OnLoadEnd,但在加载之前执行,例如 JS。因此,我解决了这个问题,以便在 OnLoadEnd 过程中等待一段时间,以防任何脚本仍然加载,然后发送通知,如下所示

procedure TForm1.OnLoadEndCust(Sender: TObject; const browser: ICefBrowser;
  const frame: ICefFrame; httpStatusCode: Integer);
var EndTime: TTime;
begin
  EndTime := IncSecond(Now, 2);

  repeat Application.ProcessMessages until (Now > EndTime);

end;

到目前为止 - 这已经足够了,但是还有其他更好或更优雅的解决方案吗?

为什么我们应该在上面的代码中使用 VisitDomProc ?当我们从 OnLoadEnd 调用它时,它似乎是不必要的。大家觉得怎么样?

关于delphi - 如何可靠地知道(以编程方式)页面何时在 Chromium 中加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13875271/

相关文章:

python - Google Depot Tools `gclient runhooks` 失败, "SYSTEMROOT"必须有效

dom - 如何在 Chrome / Chrome headless 上倾倒超过 <body> ?

delphi - 如何禁用 Chromium Embedded 中的查看源选项?

delphi - 使 TChromium 渲染抗锯齿

html - 使用Delphi检查HTML代码中是否有&lt;input&gt;对象属性值

delphi - 当 TComboBox 使用 csOwnerDrawFixed 或 csOwnerDrawVariable 时如何模拟 Windows 主题行为?

delphi - 如何隐藏其他应用程序/进程的托盘图标(从我的应用程序)?

javascript - 如何从下面的 Javascript 控制台激活选项卡?

delphi - 从 Chromium Embedded 获取 HTML 源代码

delphi - dwscript - 任何人都可以帮助编辑器调试器示例吗?