У меня есть компонент TWebBrowser, и я загружаю URL-адрес расширенного текстового редактора. После редактирования я хотел бы получить HTML-код текста (со всей его разметкой).
Взглянув на отладчик браузера, я вижу, что редактор сохраняет текст в iframe:
Я могу получить iframe с помощью этого:
NodeName := 'htmleditor_ifr';
BodyIframe := (WebBrowser1.Document as IHTMLDocument3 ).getElementById(NodeName);
Но я не знаю, как получить внутренний документ.
Какие-нибудь советы?
@ Оливье, я вижу, ваш ответ для JavaScript, я работаю с Delphi.
Мой ответ для DOM, с которым вы работаете. getElementById() также является DOM, если вы не знаете.
В Delphi есть метод getElementById, но нет метода contentDocument, поэтому, к сожалению, я не могу использовать этот подход.
Попробуйте привести возвращаемый элемент к IHTMLIFrameElement3, и тогда вы сможете получить доступ к свойству contentDocument
.
Я использую Delphi 7. Я могу найти IHTMLIFrameElement или IHTMLIFrameElement2, но не могу найти IHTMLIFrameElement3.
Тогда вы можете вместо этого привести элемент к IHTMLFrameBase2 и получить доступ к свойству contentWindow
?
В этой версии Delphi нет ни IHTMLFrameBase2, ни IHTMLIFrameBase2. Я также не могу найти интерфейс с методом contentWindow.
Вы можете попытаться привести его к IUnknown
и поместить результат в variant
, чтобы использовать позднюю привязку для доступа к свойству contentWindow...
@ Оливье, я только что узнал, как добавить все те определения, которых мне не хватало.
Это мое решение для Delphi 7.
В моей версии Delphi не было реализации IHTMLIFrameElement3, но IDE предлагает способ добавить его в ваш проект:
Компонент меню > Импорт элемента управления ActiveX
В этом диалоговом окне вы можете сгенерировать новый модуль, содержащий все определения, отсутствующие в установке Delphi 7:
CLASS_HTMLFrameElement: TGUID = '{3050F314-98B5-11CF-BB82-00AA00BDCE0B}';
IID_IHTMLIFrameElement: TGUID = '{3050F315-98B5-11CF-BB82-00AA00BDCE0B}';
IID_IHTMLIFrameElement2: TGUID = '{3050F4E6-98B5-11CF-BB82-00AA00BDCE0B}';
IID_IHTMLIFrameElement3: TGUID = '{30510433-98B5-11CF-BB82-00AA00BDCE0B}';
DIID_DispHTMLIFrame: TGUID = '{3050F51B-98B5-11CF-BB82-00AA00BDCE0B}';
CLASS_HTMLIFrame: TGUID = '{3050F316-98B5-11CF-BB82-00AA00BDCE0B}';
[...]
// *********************************************************************//
// Interface: IHTMLIFrameElement3
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {30510433-98B5-11CF-BB82-00AA00BDCE0B}
// *********************************************************************//
IHTMLIFrameElement3 = interface(IDispatch)
['{30510433-98B5-11CF-BB82-00AA00BDCE0B}']
function Get_contentDocument: IDispatch; safecall;
procedure Set_src(const p: WideString); safecall;
function Get_src: WideString; safecall;
procedure Set_longDesc(const p: WideString); safecall;
function Get_longDesc: WideString; safecall;
procedure Set_frameBorder(const p: WideString); safecall;
function Get_frameBorder: WideString; safecall;
property contentDocument: IDispatch read Get_contentDocument;
property src: WideString read Get_src write Set_src;
property longDesc: WideString read Get_longDesc write Set_longDesc;
property frameBorder: WideString read Get_frameBorder write Set_frameBorder;
end;
// *********************************************************************//
// DispIntf: IHTMLIFrameElement3Disp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {30510433-98B5-11CF-BB82-00AA00BDCE0B}
// *********************************************************************//
IHTMLIFrameElement3Disp = dispinterface
['{30510433-98B5-11CF-BB82-00AA00BDCE0B}']
property contentDocument: IDispatch readonly dispid -2147413992;
property src: WideString dispid -2147413991;
property longDesc: WideString dispid -2147413990;
property frameBorder: WideString dispid -2147413989;
end;
// *********************************************************************//
// DispIntf: DispHTMLIFrame
// Flags: (4112) Hidden Dispatchable
// GUID: {3050F51B-98B5-11CF-BB82-00AA00BDCE0B}
// *********************************************************************//
DispHTMLIFrame = dispinterface
['{3050F51B-98B5-11CF-BB82-00AA00BDCE0B}']
procedure setAttribute(const strAttributeName: WideString; AttributeValue: OleVariant;
lFlags: Integer); dispid -2147417611;
function getAttribute(const strAttributeName: WideString; lFlags: Integer): OleVariant; dispid -2147417610;
function removeAttribute(const strAttributeName: WideString; lFlags: Integer): WordBool; dispid -2147417609;
property _className: WideString dispid -2147417111;
property id: WideString dispid -2147417110;
property tagName: WideString readonly dispid -2147417108;
// more
Получив это, я последовал советам @Olivier:
NodeName := 'htmleditor_ifr';
BodyIframe := (WebBrowser1.Document as IHTMLDocument3 ).getElementById(NodeName);
ContentHTML := (((BodyIframe as IHTMLIFrameElement3 ).contentDocument) as IHTMLDocument2 );
Body := ContentHTML.body.innerHTML;