2013-01-22 60 views
8

Tôi đang cố gắng liệt kê các nút DOM bằng cách sử dụng mã sau (dưới XE2).Liệt kê các nút DOM trong TChromium

Tôi đã mượn hầu hết điều này từ các câu trả lời được đưa ra ở đây trong SO, nhưng vì lý do nào đó, nó không làm bất cứ điều gì.

IOW, ProcessDOM() không bao giờ được gọi.

Và tôi kết thúc trí thông minh của mình.

Ai đó có thể cho tôi biết tôi đang làm gì sai ở đây.

Xin cảm ơn trước.

procedure ProcessNode(ANode: ICefDomNode); 
var 
    Node1: ICefDomNode; 
begin 
    if Assigned(ANode) then begin 
    Node1 := ANode.FirstChild; 
    while Assigned(Node1) do begin 
     {Do stuff with node} 
     ProcessNode(Node1); 
     Node1 := Node1.NextSibling; 
    end; 
    end; 
end; 

procedure ProcessDOM(const ADocument: ICefDomDocument); 
begin 
    ProcessNode(ADocument.Body); 
end; 

procedure TMainForm.Chrome1LoadEnd(Sender: TObject; const ABrowser: ICefABrowser; const AFrame: ICefAFrame; AStatus: Integer); 
begin 
    if Assigned(AFrame) then AFrame.VisitDomProc(ProcessDOM); 
end; 
+0

Theo như tôi nhớ, đã có phiên bản Chromium trong đó truy cập DOM không hoạt động chút nào. Phiên bản nào bạn đang sử dụng ? – TLama

+0

Tôi đang sử dụng SVN mới nhất 'Delphi Chromium Embedded 3'. Bạn có biết phiên bản nào hoạt động không? – Adem

+0

Hm, có vẻ như nó không hoạt động trong ảnh chụp nhanh hiện tại của Chromium 3 (tất nhiên là tôi đã sửa lỗi chính tả 'ICefABrowser' và 'ICefAFrame' từ đây). Mã của bạn IMHO sẽ hoạt động, nhưng không. Truy cập DOM hoạt động tốt trong một số phiên bản cũ của Chromium cũ (không phải v3) và theo như tôi nhớ, ảnh chụp nhanh mới của Chromium cũ cũng đã bị hỏng. Tôi sẽ đề nghị để gửi một lỗi (nếu không có) hoặc liên hệ với tác giả. Tôi sợ tôi không thể giúp bạn với điều này nhiều hơn. – TLama

Trả lời

1

Tôi đã gặp vấn đề tương tự và tôi đã sử dụng trình diễn demo kèm theo dcef3. Với sau nó hoạt động.

type TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn) 
     protected 
     function OnProcessMessageReceived(const browser: ICefBrowser; 
      sourceProcess: TCefProcessId; const message: ICefProcessMessage): Boolean; 
      override; 
     end; 

    Chromium1.browser.SendProcessMessage(PID_RENDERER,TCefProcessMessageRef.New('visitdom')); 

    function TCustomRenderProcessHandler.OnProcessMessageReceived(
     const browser: ICefBrowser; sourceProcess: TCefProcessId; 
     const message: ICefProcessMessage): Boolean; 
    begin if (message.Name = 'visitdom') then begin browser.MainFrame.VisitDomProc(
     procedure(const doc: ICefDomDocument) begin 
    ProcessNode(Doc.Body); 
       end) 
      end); 
      Result := True; 
     end; end; 

    initialization 
     CefRenderProcessHandler := TCustomRenderProcessHandler.Create; 
0

Bạn cần thêm thủ tục vào trình xử lý. quy trình ProcessNode (Mã hóa: ICefDomNode);

đọc này: 1

+0

Câu trả lời này không có ý nghĩa. Nó liên kết với câu hỏi này, và tại sao nó cần thêm một thủ tục? Bạn có thể giải thích thêm được không? –

0

Như blog điểm này ra, Khó khăn chính khi truy cập vào một trang DOM render là bạn chỉ có thể làm như vậy trong quá trình tương tự như các renderer liên quan cho trang đó.

Bạn không thể truy cập dom từ chuỗi trình duyệt, bạn phải làm điều đó trong chuỗi trình kết xuất.

Thứ nhất, chuyển tiếp thư (như visitdom) từ quá trình duyệt để render quá trình

procedure TMainForm.crmLoadEnd(Sender: TObject; const browser: ICefBrowser; 
    const frame: ICefFrame; httpStatusCode: Integer); 
var 
    msg : ICefProcessMessage; 
begin 
    if IsMain(browser, frame) then 
    FLoading := False; 

    msg := TCefProcessMessageRef.New('visitdom'); 
    browser.SendProcessMessage(PID_RENDERER, msg); 
end; 

Thứ hai, tạo ra một TCustomRenderProcessHandler để xử lý các tin nhắn, gửi kết quả trở lại processs trình duyệt.

function TCustomRenderProcessHandler.OnProcessMessageReceived(
    const browser: ICefBrowser; sourceProcess: TCefProcessId; 
    const message: ICefProcessMessage): Boolean; 
begin 
    Result := False; 
    if (message.Name = 'visitdom') then 
    begin 
     browser.MainFrame.VisitDomProc(
     procedure(const doc: ICefDomDocument) 
      function ProcessNode(ANode: ICefDomNode) : String; 
      var 
      Node: ICefDomNode; 
      begin 
      Result := 'Not Found'; 
      if Assigned(ANode) then 
      begin 
       Node := ANode.FirstChild; 
       while Assigned(Node) do 
       begin 
       if Node.ElementTagName='DIV' then 
       begin 
        if Node.GetElementAttribute('class')='tv-panels' then 
        begin 
        Result := 'Found'; 
        Exit; 
        end; 
       end; 
       ProcessNode(Node); 
       Node := Node.NextSibling; 
       end; 
      end; 
      end; 
     var msg : ICefProcessMessage; 
     begin 
      msg := TCefProcessMessageRef.New('visitdom'); 
      msg.ArgumentList.SetString(0, processNode(doc.Body)); 
      browser.SendProcessMessage(PID_BROWSER, msg); 
     end); 
     Result := True; 
    end; 
end; 

Thứ ba, Trên trình duyệt, hãy tạo trình xử lý để xử lý thông điệp được gửi lại từ quá trình kết xuất.

procedure TMainForm.crmProcessMessageReceived(Sender: TObject; 
    const browser: ICefBrowser; sourceProcess: TCefProcessId; 
    const message: ICefProcessMessage; out Result: Boolean); 
begin 
    Result := False; 
    if (message.Name = 'visitdom') then 
    begin 
    StatusBar.SimpleText := message.ArgumentList.GetString(0); 
    Result := True; 
    end; 
end; 

Hãy cẩn thận, trong khi gỡ lỗi, đặt điểm ngắt trong quá trình hiển thị không bao giờ hoạt động. Nó sẽ không bao giờ đạt tới đó.

Các vấn đề liên quan