如何在WebBrowser控件中注入Javascript?
我已经试过了:
string newScript = textBox1.Text; HtmlElement head = browserCtrl.Document.GetElementsByTagName("head")[0]; HtmlElement scriptEl = browserCtrl.Document.CreateElement("script"); lblStatus.Text = scriptEl.GetType().ToString(); scriptEl.SetAttribute("type", "text/javascript"); head.AppendChild(scriptEl); scriptEl.InnerHtml = "function sayHello() { alert('hello') }";
scriptEl.InnerHtml和scriptEl.InnerText都给出错误:
System.NotSupportedException: Property is not supported on this type of HtmlElement. at System.Windows.Forms.HtmlElement.set_InnerHtml(String value) at SForceApp.Form1.button1_Click(Object sender, EventArgs e) in d:\jsight\installs\SForceApp\SForceApp\Form1.cs:line 31 at System.Windows.Forms.Control.OnClick(EventArgs e) at System.Windows.Forms.Button.OnClick(EventArgs e) at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ButtonBase.WndProc(Message& m) at System.Windows.Forms.Button.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
有没有一种简单的方法可以将脚本注入到dom中?
解决方案
我们要做的是使用Page.RegisterStartupScript(key,script)
:
有关更多详细信息,请参见此处:http://msdn.microsoft.com/zh-cn/library/aa478975.aspx
我们基本上要做的是构建javascript字符串,将其传递给该方法并为其指定一个唯一的ID(以防我们尝试在页面上将其注册两次。)
编辑:这就是我们所说的触发快乐。随意降低它。 :)
我们始终可以使用" DocumentStream"或者" DocumentText"属性。
对于使用HTML文档,我建议使用HTML Agility Pack。
HTML文档的托管包装没有完全实现所需的功能,因此我们需要使用MSHTML API来完成所需的工作:
1)添加对MSHTML的引用,该引用在COM引用下可能被称为" Microsoft HTML对象库"。
2)添加"使用mshtml;"到名称空间。
3)获取对脚本元素的IHTMLElement的引用:
IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;
4)调用insertAdjacentText方法,其第一个参数值为" afterBegin"。此处列出了所有可能的值:
iScriptEl.insertAdjacentText("afterBegin", "function sayHello() { alert('hello') }");
5)现在,我们将能够在scriptEl.InnerText属性中看到代码。
Hth,
理查德
由于某种原因,Richard的解决方案对我而言不起作用(insertAdjacentText失败,并带有异常)。但是,这似乎可行:
HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0]; HtmlElement scriptEl = webBrowser1.Document.CreateElement("script"); IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement; element.text = "function sayHello() { alert('hello') }"; head.AppendChild(scriptEl); webBrowser1.Document.InvokeScript("sayHello");
该答案说明了如何将" IHTMLScriptElement"接口添加到项目中。
如果我们真正想要的只是运行javascript,这将是最简单的(VB .Net):
MyWebBrowser.Navigate("javascript:function foo(){alert('hello');}foo();")
我想这不会"注入"它,但是它将运行函数(如果我们要这样做的话)。 (以防万一我们使问题过于复杂。)并且,如果我们能弄清楚如何注入javascript,请将其放入函数" foo"的主体中,然后让javascript为我们注入。
另外,在.NET 4中,如果使用dynamic关键字,这甚至更加容易:
dynamic document = this.browser.Document; dynamic head = document.GetElementsByTagName("head")[0]; dynamic scriptEl = document.CreateElement("script"); scriptEl.text = ...; head.AppendChild(scriptEl);
这是使用mshtml的解决方案
IHTMLDocument2 doc = new HTMLDocumentClass(); doc.write(new object[] { File.ReadAllText(filePath) }); doc.close(); IHTMLElement head = (IHTMLElement)((IHTMLElementCollection)doc.all.tags("head")).item(null, 0); IHTMLScriptElement scriptObject = (IHTMLScriptElement)doc.createElement("script"); scriptObject.type = @"text/javascript"; scriptObject.text = @"function btn1_OnClick(str){ alert('you clicked' + str); }"; ((HTMLHeadElementClass)head).appendChild((IHTMLDOMNode)scriptObject);