gpt4 book ai didi

javascript - 将脚本元素添加到现有的 TWebBrowser 文档

转载 作者:搜寻专家 更新时间:2023-11-01 05:31:16 25 4
gpt4 key购买 nike

在这个周末的几个 SO 问题的提示下,我决定看看我是否能弄清楚如何将 Html 元素中的一些 javascript 添加到 TWebBrowser 中加载的文档中。这样做,我遇到了一个奇怪的问题,也许有人可以解释。

这是我的 Html 文档

<html>
<body>
Something
<br>
<div id="forscript">some more text</div>
</body>
</html>

还有我想添加的 javascript 元素

<script type="text/javascript" defer="false">{alert('hello');}</script>

我将其作为脚本参数传递给下面的 AddScript()。

这是我的代码(doc2是从WebBrowser获取的IHtmlDocument2):

procedure TForm1.AddScript(const Script : String);
var
Element : IHtmlElement;
Doc3 : IHtmlDocument3;
begin
Doc2.QueryInterface(IHtmlDocument3, Doc3);
Element := Doc3.GetElementByID('forscript');
Element.innerHTML := Element.innerHTML + Script;
end;

这工作正常,但是......

赋值的RHS上的Element.innerHTML的原因很简单,我发现如果 RHS 包含 Script js,则 js 不会执行。我的问题是,为什么不呢,是否有更简单的替代方法,比如以某种方式在代码中创建 IHtmlScriptElement 并将其插入 DOM 中?显然,我头脑简单的解决方法只是将文本添加到元素已经包含,但我有点难以相信真正知道自己在做什么的人会发现有必要。

FWIW #1:我尝试使用 Element.insertAdjacentHtml 来添加脚本,但得到的行为与我刚才描述的相同,除了脚本之外还需要插入一些东西来获取要执行的脚本,所以我想知道这是否与 DOM 在对其进行更改后的处理方式有关。

FWIW #2:我使用了 Element.innerHtml 路由,因为 TWebBrowser/MSHTML.Pas 拒绝了我的尝试在代码中创建 IHtmlScriptElement; AFAICS,试图使用任何MSHTML.Pas 中的 CohtmlXXXElement 例程引发“类未注册”异常,这似乎证实了我在某个地方遇到的这个教区的@kobik 的评论。

(顺便说一句,在 Win7 64 位上使用 D7 + IE11)

最佳答案

这是一个如何使用 IHtmlScriptElement 的完整示例。HTML 在应用程序启动时加载。Button1Click 下的代码将 javascript 添加到 DOM 并执行它:

unit u_frm_SO27091639;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtrls, SHDocVw, MsHtml, ActiveX;

type
TForm1 = class(TForm)
WebBrowser1: TWebBrowser;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure LoadDocFromString(Webbrowser : TWebbrowser);

var
Strm : TStringStream;
Adapter : TStreamAdapter;

begin
WebBrowser.Navigate('about:blank');
// warning - don't use this trick in production code, use the `OnDocumentComplete` event
while WebBrowser.ReadyState <> READYSTATE_INTERACTIVE do
Application.ProcessMessages;
// end of warning
Strm := TStringStream.Create;
try
Strm.WriteString('<html><body>Something<br></body></html>');
Strm.Seek(0, 0);
Adapter := TStreamAdapter.Create(Strm);
(WebBrowser.Document as IPersistStreamInit).Load(Adapter) ;
finally
Strm.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);

var
Doc2 : IHtmlDocument2;
Script : IHtmlDOMNode;
HTMLWindow: IHTMLWindow2;

begin
Doc2 := Webbrowser1.Document as IHtmlDocument2;
if Assigned(Doc2.body) then
begin
Script := Doc2.createElement('script') as IHTMLDOMNode;
(Script as IHTMLScriptElement).text := 'function helloWorld() { alert("hello world!") }';
(Doc2.body as IHtmlDomNode).appendChild(Script);
HTMLWindow := Doc2.parentWindow;
if Assigned(HTMLWindow) then
HTMLWindow.execScript('helloWorld()', 'JavaScript')
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
LoadDocFromString(Webbrowser1);
end;

end.

关于javascript - 将脚本元素添加到现有的 TWebBrowser 文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27091639/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com