2012-05-20 17 views
5

टीएच क्रोमियम उदाहरण से वर्तमान वेब दस्तावेज़ में एम्बेडेड एक विशेष डोम नोड प्राप्त करने के लिए, इसकी आईडी का उपयोग करके, आप ICefDomDocument.getElementById() का उपयोग करते हैं। लेकिन आप NAME विशेषता द्वारा तत्व कैसे प्राप्त करते हैं? जावास्क्रिप्ट document.getElementsByName() विधि और TWebBrowser (कि IE लपेटता) एक ऐसी ही कॉल किया है है, लेकिन मैं कैसे TChromium के साथ ऐसा करने को समझ नहीं सकता। मुझे कुछ DOM तत्व ढूंढने की आवश्यकता है जिनमें NAME विशेषताएँ हैं लेकिन कोई आईडी विशेषता नहीं है। मैं ceflib इकाई खोज की है और कुछ भी है कि यह करना होगा नहीं देखा।डेल्फी क्रोमियम एम्बेडेड में नाम से तत्व कैसे प्राप्त करें?

साइड सवाल। अगर किसी के पास टीएचरोमियम "व्यंजनों" शैली साइट या दस्तावेज़ का लिंक है तो मैं इसका उपयोग कर सकता हूं।

अद्यतन: उत्तर देने का इंतजार करते समय मैं getElementsbyName() प्राप्त करने के लिए निम्नलिखित कोड के साथ आया हूं। मुझे पूरे डोम पेड़ को स्कैन करने से कुछ तेज चाहिए। यदि आप देखते हैं कुछ कोड में गलत जाने मुझे पता है:

type 
    TDynamicCefDomNodeArray = array of ICefDomNode; 


// Given a Chromium document interface reference and a NAME attribute to search for, 
// return an array of all DOM nodes whose NAME attribute matches the desired. 
function getElementsByName(ADocument: ICefDomDocument; theName: string): TDynamicCefDomNodeArray; 

    // Get all the elements with a particular NAME attribute value and return 
    // an array of them. 
    procedure getElementsByName1(intfParentNode: ICefDomNode; theName: string; var aryResults: TDynamicCefDomNodeArray); 
    var 
     oldLen: integer; 
     intfChildNode: ICefDomNode; 
     theNameAttr: string; 
    begin 
     Result := nil; 
     intfChildNode := nil; 

     if Assigned(intfParentNode) then 
     begin 
      // Attributes are case insensitive. 
      theNameAttr := intfParentNode.GetElementAttribute('name'); 

      if AnsiSameText(theNameAttr, theName) then 
      begin 
       // Name attribute match. Add it to the results array. 
       oldLen := Length(aryResults); 
       SetLength(aryResults, oldLen + 1); 
       aryResults[oldLen] := intfParentNode; 
      end; // if AnsiSameText(intfParentNode.Name, theName) then 

      // Does the parent node have children? 
      if intfParentNode.HasChildren then 
      begin 
       intfChildNode := intfParentNode.FirstChild; 

       // Scan them. 
       while Assigned(intfChildNode) do 
       begin 
        getElementsByName1(intfChildNode, theName, aryResults); 

        if Assigned(intfChildNode) then 
         intfChildNode := intfChildNode.NextSibling; 
       end; 
      end; // if intfParentNode.HasChildren then 
     end; // if Assigned(intfParentNode) then 
    end; 

    // --------------------------------------------------------------- 

var 
    intfCefDomNode: ICefDomNode; 
begin 
    intfCefDomNode := nil; 
    Result := nil; 

    if Assigned(ADocument) then 
    begin 
     // Check the header. 
     intfCefDomNode := ADocument.Document; 

     if Assigned(intfCefDomNode) then 
     begin 
      // Check the parent. 
      getElementsByName1(intfCefDomNode, theName, Result); 
     end; // if Assigned(intfCefDomNode) then 
    end; // if Assigned(ADocoument) then 
end; 

// --------------------------------------------------------------- 
+0

मुझे नहीं लगता कि यह मिश्रण और कला सामान के राज्य के साथ 10 साल पुराने प्रौद्योगिकी मिलान करने के लिए बुद्धिमान है और यह एक मिल गया और स्थायी समाधान बनने के लिए उम्मीद करते हैं। इस विशेष मामले में, टीच्रोमियम डेल्फ़ 6 का समर्थन नहीं करता है। Http://code.google.com/p/delphichromiumembedded/ –

+0

@ जेरोइन, ['टीच्रोमियम'] (http://code.google.com/p/delphichromiumembedded /) डेल्फी 6 का समर्थन नहीं करता है (हालांकि इसके लिए कोई पैकेज नहीं है), लेकिन इसका मतलब यह नहीं है कि यह वहां काम नहीं कर सका। मेरे पास डेल्फी 200 है, जो असमर्थित है, लेकिन स्रोत की तलाश में, वहां कुछ भी नहीं है जो उपयोग को बाधित कर सकता है ;-) – TLama

+0

@TLama अगर मेरा दिमाग मुझे काफी अच्छी तरह से सेवा देता है, डेल्फी 7 ने COM सामान लपेटने से संबंधित कुछ फ़िक्स पेश किए हैं। यह डेल्फी 6 का समर्थन नहीं करने का एक कारण हो सकता है। मैं रॉबर्ट को टीएचरोमियम टीम के साथ इस धारणा को सत्यापित करने की सलाह दूंगा। –

उत्तर

3

जावास्क्रिप्ट का getElementsByName या MSHTML getElementsByNameChromium Embedded है और न ही इस समय अपने डेल्फी आवरण में बनाया की तरह कोई समारोह नहीं है। आप इसे केवल सभी डीओएम तत्वों पर पुनरावृत्त करके हल कर सकते हैं, उदा। इस तरह अपने स्वयं के डोम आगंतुक वर्ग बनाने के द्वारा:

कृपया ध्यान दें VisitDom प्रक्रिया अतुल्यकालिक है, इसलिए इसे तुरंत वापस लौट (वास्तव में से पहले डोम आगंतुक अपने visit खत्म) है और यह समय यह मार डाला है पर डोम का एक स्नैपशॉट के साथ काम करता ।

type 
    TElementNameVisitor = class(TCefDomVisitorOwn) 
    private 
    FName: string; 
    protected 
    procedure visit(const document: ICefDomDocument); override; 
    public 
    constructor Create(const AName: string); reintroduce; 
    end; 

procedure ProcessElementsByName(const AFrame: ICefFrame; const AName: string); 
var 
    Visitor: TElementNameVisitor; 
begin 
    if Assigned(AFrame) then 
    begin 
    Visitor := TElementNameVisitor.Create(AName); 
    AFrame.VisitDom(Visitor); 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ProcessElementsByName(Chromium1.Browser.MainFrame, 'NameAttributeValue'); 
end; 

{ TDOMElementNameVisitor } 

constructor TElementNameVisitor.Create(const AName: string); 
begin 
    inherited Create; 
    FName := AName; 
end; 

procedure TElementNameVisitor.visit(const document: ICefDomDocument); 

    procedure ProcessNode(ANode: ICefDomNode); 
    var 
    Node: ICefDomNode; 
    begin 
    if Assigned(ANode) then 
    begin 
     Node := ANode.FirstChild; 
     while Assigned(Node) do 
     begin 
     if Node.GetElementAttribute('name') = FName then 
     begin 
      // do what you need with the Node here 
      ShowMessage(Node.GetElementAttribute('value')); 
     end; 
     ProcessNode(Node); 
     Node := Node.NextSibling; 
     end; 
    end; 
    end; 

begin 
    ProcessNode(document.Body); 
end; 
+1

पुन: पहिया reinventing। उद्देश्य पर नहीं, केवल डेल्फी के साथ क्रोमियम का उपयोग करते समय मैंने जो पाया, उसका उपयोग करके (मुख्य पोस्ट पर आपकी टिप्पणी का मेरा उत्तर देखें)। –

+0

तो मैं इसे ले एक TCefDomVisitorOwn वंशज के साथ बुला यात्रा आगंतुक पैटर्न को लागू करता है? दूसरे शब्दों में, सीईएफ डोम में सभी नोड्स के लिए उस पैटर्न को लागू करेगा, जो आपके लिए नोड पेड़ के माध्यम से रिकर्सिव वंश को संभालेगा? अगर ऐसा है तो यह बहुत अच्छा है लेकिन मैं पूरी तरह से सुनिश्चित होना चाहता हूं इसलिए मैं पुष्टि की मांग कर रहा हूं। –

+0

नहीं, पुनरावृत्ति आपको अभी भी अपने आप करना है। 'VisitDom' विधि का उपयोग करने का अंतर यह है कि यह वर्तमान डोम स्थिति की एक प्रति (एक स्नैपशॉट) बनाता है। मेरे उदाहरण में 'TElementNameVisitor.visit', दस्तावेज़ की एक प्रतिलिपि के साथ काम करता स्वयं दस्तावेज़ (जो समय आप पुनरावृति पर बदला जा सकता है) के साथ नहीं। मुझे नहीं पता कि यह तेज़ है, यह सिर्फ सुरक्षित है। – TLama

संबंधित मुद्दे