使用WebBrowser.Document.InvokeScript调用JavaScript对象方法

9
在我的WinForms应用程序中,我需要从WebBrowser控件调用javascript函数。我使用了Document.InvokeScript,并且它能够完美地处理独立的函数,例如:
Document.InvokeScript("function").

但是当我想调用JavaScript对象方法时,例如:
Document.InvokeScript("obj.method")

它不能工作。有没有办法让它工作?或者解决这个问题的不同方法?不要改变JavaScript代码中的任何内容!

提前感谢:)


假设我在JavaScript中有以下代码: obj = {method : function() {alert("...)}, 我想从我的Web浏览器控件调用obj.method()。 - Brazol
3个回答

9

文档中的示例不包括括号。

private void InvokeScript()
{
    if (webBrowser1.Document != null)
    {
        HtmlDocument doc = webBrowser1.Document;
        String str = doc.InvokeScript("test").ToString() ;
        Object jscriptObj = doc.InvokeScript("testJScriptObject");
        Object domOb = doc.InvokeScript("testElement");
    }
}

尝试

Document.InvokeMethod("obj.method");

请注意,如果您使用HtmlDocument.InvokeScript方法(String,Object []),则可以传递参数。

编辑

看起来您不是唯一遇到这个问题的人:HtmlDocument.InvokeScript-调用对象的方法。您可以像该链接的发布者建议的那样制作“代理函数”。基本上,您有一个调用对象函数的函数。这不是一个理想的解决方案,但它肯定会起作用。我将继续寻找是否可能实现此功能。
同一问题的另一篇文章:使用WebBrowser.Document.InvokeScript()搞乱外部JavaScript。CodeProject上C.Groß提出了有趣的解决方案:
private string sendJS(string JScript) {
    object[] args = {JScript};
    return webBrowser1.Document.InvokeScript("eval",args).ToString();
}

您可以将其作为HtmlDocument的扩展方法,并调用该方法来运行您的函数,在传递的字符串中使用括号、参数等所有内容,因为它只是传递给一个eval函数。
看起来HtmlDocument不支持调用现有对象上的方法,只支持全局函数。 :(

哦,抱歉,那是我在写帖子时犯的错误。在我的代码中,我从未使用过括号(我已经编辑了帖子)。现在有什么想法可能出了问题吗? - Brazol
第二个解决方案非常好!谢谢,因为在您链接的帖子中,我的主要担忧是不改变JavaScript代码。所以再次感谢,这正是我想要的 :) - Brazol
第二个解决方案非常棒,节省了我数小时的时间。 - user2475983

3

很遗憾,使用WebBrowser.Document.InvokeScript无法直接调用对象方法。

解决方案是在JavaScript端提供一个全局函数,可以重定向您的调用。最简单的形式如下:

function invoke(method, args) {

    // The root context is assumed to be the window object. The last part of the method parameter is the actual function name.
    var context = window;
    var namespace = method.split('.');
    var func = namespace.pop();

    // Resolve the context
    for (var i = 0; i < namespace.length; i++) {
        context = context[namespace[i]];
    }

    // Invoke the target function.
    result = context[func].apply(context, args);
}

在您的.NET代码中,您可以按以下方式使用它:

var parameters = new object[] { "obj.method", yourArgument };
var resultJson = WebBrowser.Document.InvokeScript("invoke", parameters);

正如您提到的,由于无法更改您现有的JavaScript代码,因此您将不得不以某种方式注入上述JavaScript方法。幸运的是,WebBrowser控件也可以通过调用eval()方法来为您完成:

WebBrowser.Document.InvokeScript("eval", javaScriptString);

如果您需要更加强大和完整的实现,可以参考我编写的WebBrowser工具以及解释ScriptingBridge的文章,该工具专门旨在解决您所描述的问题。


2
 webBrowser.Document.InvokeScript("execScript", new object[] { "this.alert(123)", "JavaScript" })

你应该像这样

 webBrowser.Document.InvokeScript("execScript", new object[] { "obj.method()", "JavaScript" })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接