Aby uzyskać konkretny węzeł DOM osadzony w bieżącym dokumencie WWW z instancji TChromium, używając jej identyfikatora, należy użyć ICefDomDocument.getElementById(). Ale jak znaleźć elementy według atrybutu NAME? JavaScript ma metodę document.getElementsByName() i TWebBrowser (która owija IE) ma podobne wywołanie, ale nie mogę wymyślić, jak to zrobić z TChromium. Potrzebuję znaleźć elementy DOM, które mają atrybuty NAME, ale nie mają atrybutów ID. Przeszukałem jednostkę ceflib i nie widziałem niczego, co mogłoby to zrobić.Jak zdobyć elementy według nazwy w Delphi Chromium Embedded?
Pytanie boczne. Jeśli ktoś ma link do strony z "recepturami" w stylu TChromium, mógłbym go użyć.
AKTUALIZACJA: Czekając na odpowiedź, wymyślam następujący kod do wykonywania getElementsbyName(). Chciałbym czegoś szybszego niż skanowanie całego drzewa DOM. Jeśli widzisz coś złego w kodzie daj mi znać:
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;
// ---------------------------------------------------------------
Nie sądzę, że jest mądry, aby łączyć ze sobą 10-letnią technologię ze stanem rzeczy sztuki i oczekiwać, że aby stać się znaleźć i stabilne rozwiązanie. W tym konkretnym przypadku TChromium nie obsługuje Delph 6. http://code.google.com/p/delphichromiumembedded/ –
@Jeroen, ['TChromium'] (http://code.google.com/p/delphichromiumembedded /) nie obsługuje Delphi 6 (nie ma dla niego pakietu), ale nie oznacza to, że nie może tam pracować. Mam Delphi 2009, który jest również nieobsługiwany, ale patrząc na źródło, nie ma nic, co mogłoby powstrzymać jego użycie ;-) – TLama
@TLama, jeśli mój umysł dobrze mi służy, Delphi 7 wprowadziła sporo poprawek związanych z zawijaniem rzeczy COM. To może być powód, by nie wspierać Delphi 6. Poleciłbym Robertowi zweryfikować to założenie z zespołem TChromium. –