jsi*_*ght 81 .net javascript c# webbrowser-control winforms
我试过这个:
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') }";
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
是否有一种简单的方法将脚本注入dom?
Ata*_*hev 100
出于某种原因,理查德的解决方案在我的结尾不起作用(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");
Run Code Online (Sandbox Code Playgroud)
这个答案解释了如何让IHTMLScriptElement
界面进入你的项目.
typ*_*ppo 48
HtmlDocument doc = browser.Document;
HtmlElement head = doc.GetElementsByTagName("head")[0];
HtmlElement s = doc.CreateElement("script");
s.SetAttribute("text","function sayHello() { alert('hello'); }");
head.AppendChild(s);
browser.Document.InvokeScript("sayHello");
Run Code Online (Sandbox Code Playgroud)
(在.NET 4/Windows Forms App中测试)
编辑:修复了函数集中的案例问题.
小智 31
这是我在完成此工作后找到的最简单的方法:
string javascript = "alert('Hello');";
// or any combination of your JavaScript commands
// (including function calls, variables... etc)
// WebBrowser webBrowser1 is what you are using for your web browser
webBrowser1.Document.InvokeScript("eval", new object[] { javascript });
Run Code Online (Sandbox Code Playgroud)
全局JavaScript函数的eval(str)
作用是解析和执行str中编写的任何内容.在这里查看w3schools ref.
jus*_*ase 21
此外,在.NET 4中,如果使用dynamic关键字,则更容易:
dynamic document = this.browser.Document;
dynamic head = document.GetElementsByTagName("head")[0];
dynamic scriptEl = document.CreateElement("script");
scriptEl.text = ...;
head.AppendChild(scriptEl);
Run Code Online (Sandbox Code Playgroud)
Eya*_*yal 17
如果您真正想要的是运行javascript,这将是最简单的(VB .Net):
MyWebBrowser.Navigate("javascript:function foo(){alert('hello');}foo();")
Run Code Online (Sandbox Code Playgroud)
我想这不会"注入"但它会运行你的功能,如果这就是你所追求的.(以防万一你过度复杂的问题.)如果你能弄清楚如何注入javascript,把它放到函数"foo"的主体中,让javascript为你做注入.
Zer*_*nce 10
HTML文档的托管包装器并不能完全实现您需要的功能,因此您需要深入了解MSHTML API以实现您的目标:
1)添加对MSHTML的引用,它将在COM引用下被称为"Microsoft HTML Object Library" .
2)添加'using mshtml;' 到您的命名空间.
3)获取对脚本元素的IHTMLElement的引用:
IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;
Run Code Online (Sandbox Code Playgroud)
4)调用insertAdjacentText方法,第一个参数值为"afterBegin".此处列出了所有可能的值:
iScriptEl.insertAdjacentText("afterBegin", "function sayHello() { alert('hello') }");
Run Code Online (Sandbox Code Playgroud)
5)现在,您将能够在scriptEl.InnerText属性中看到代码.
理查德
小智 8
我相信从c#在WebBrowser控件HTML文档中注入Javascript的最简单的方法是调用"execStrip"方法,并将代码作为参数注入.
在此示例中,javascript代码在全局范围内注入并执行:
var jsCode="alert('hello world from injected code');";
WebBrowser.Document.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" });
Run Code Online (Sandbox Code Playgroud)
如果要延迟执行,请注入函数并在以下情况后调用它们:
var jsCode="function greet(msg){alert(msg);};";
WebBrowser.Document.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" });
...............
WebBrowser.Document.InvokeScript("greet",new object[] {"hello world"});
Run Code Online (Sandbox Code Playgroud)
这适用于Windows窗体和WPF WebBrowser控件.
此解决方案不是跨浏览器,因为"execScript"仅在IE和Chrome中定义.但问题是关于Microsoft WebBrowser控件和IE是唯一支持的.
对于有效的跨浏览器方法来注入javascript代码,请使用新的关键字创建一个Function对象.此示例使用注入的代码创建一个匿名函数并执行它(javascript实现闭包,函数可以访问全局空间而不会出现局部变量污染).
var jsCode="alert('hello world');";
(new Function(code))();
Run Code Online (Sandbox Code Playgroud)
当然,你可以延迟执行:
var jsCode="alert('hello world');";
var inserted=new Function(code);
.................
inserted();
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你
作为已接受答案的后续内容,这是IHTMLScriptElement
接口的最小定义,不需要包含其他类型库:
[ComImport, ComVisible(true), Guid(@"3050f28b-98b5-11cf-bb82-00aa00bdce0b")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
[TypeLibType(TypeLibTypeFlags.FDispatchable)]
public interface IHTMLScriptElement
{
[DispId(1006)]
string text { set; [return: MarshalAs(UnmanagedType.BStr)] get; }
}
Run Code Online (Sandbox Code Playgroud)
因此,WebBrowser控件派生类中的完整代码如下所示:
protected override void OnDocumentCompleted(
WebBrowserDocumentCompletedEventArgs e)
{
base.OnDocumentCompleted(e);
// Disable text selection.
var doc = Document;
if (doc != null)
{
var heads = doc.GetElementsByTagName(@"head");
if (heads.Count > 0)
{
var scriptEl = doc.CreateElement(@"script");
if (scriptEl != null)
{
var element = (IHTMLScriptElement)scriptEl.DomElement;
element.text =
@"function disableSelection()
{
document.body.onselectstart=function(){ return false; };
document.body.ondragstart=function() { return false; };
}";
heads[0].AppendChild(scriptEl);
doc.InvokeScript(@"disableSelection");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个使用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);
Run Code Online (Sandbox Code Playgroud)