如何在WebBrowser控件中检测Javascript执行

如何在WebBrowser控件中检测Javascript执行,javascript,c#,browser,webbrowser-control,dom-events,Javascript,C#,Browser,Webbrowser Control,Dom Events,我的C#应用程序中有一个WebBrowser控件。web浏览器由用户控制,也就是说,用户可以加载其计算机可以在web上访问的任何网页(当然受代理、主机文件等的限制) 我需要知道并在web浏览器组件中加载的页面内有Javascript调用时得到通知 第一个例子:给定这样一个链接 <a href="javascript:void(0)" onclick="jsFunct();">test</a> $(document).ready(function () {

我的C#应用程序中有一个
WebBrowser
控件。web浏览器由用户控制,也就是说,用户可以加载其计算机可以在web上访问的任何网页(当然受代理、主机文件等的限制)

我需要知道并在web浏览器组件中加载的页面内有Javascript调用时得到通知

第一个例子:给定这样一个链接

<a href="javascript:void(0)" onclick="jsFunct();">test</a>
 $(document).ready(function () { 
        //Add click event for every anchor on the page loaded- note this merely alerts text on click. you can however add your own function
        $("a").click(function (e) { alert($(this).text()); return false;}) 
    }); 

当用户单击链接时,我需要知道函数“jsFunct”已被调用

第二个例子:给一个像

<script type="text/javascript">
    window.setTimeout("jsFunct()", 1000);
</script>

setTimeout(“jsFunct()”,1000);
我需要知道,在脚本执行1秒钟后,函数jsFunct已经被调用

最好是在调用函数时触发事件。如果事件可以执行Javascript代码,或者至少参数中的函数名,那也太好了

编辑:


即使问题与webbrowser组件有关,任何允许用户检测javascript激活(甚至通过js)的东西都可以,能够注入一个处理javascript事件的js,并将其传递给wb控件,触发它可以处理的事件。

关于webbrowser加载事件

  • 注入Jquery
  • 注入监视器脚本
  • ,


    克里希纳所回答的是纯javascript附加到事件中,但是我看到您可能需要将其附加到所有标记(a、p、div、input)等以及附加到每个标记的所有事件中


    我认为另一种方法是在.net中使用BHO(浏览器助手对象),如果没有,并且你擅长VC++和MFC,你也可以使用Windows钩子。

    你可以使用
    window.external
    在JavaScript中启动全局函数时调用C#方法。有关window.external的详细信息,请参见

    您需要设置ObjectForScripting:才能使其工作

    以@Krishna的答案添加JavaScript(但删除jQuery,因为它不需要):

    下面的JavaScript(InjectMonitor.js)将查找所有全局函数并附加指定的处理程序:

    function augment(withFn) {
        var name, fn;
        for (name in window) {
            fn = window[name];
            if (typeof fn === 'function') {
                window[name] = (function(name, fn) {
                    var args = arguments;
                    return function() {
                        withFn.apply(this, args);
                        fn.apply(this, arguments);
    
                    };
                })(name, fn);
            }
        }
    }
    
    augment(function(name, fn) {
        console.log("calling " + name, fn);
    
        // window.external.yourC#method
    });
    
    在本例中,取自,它只记录对控制台的调用;但是使用window.external,您可以向C#应用程序发送一些消息,详细说明从客户端调用了什么函数


    最后,这里是一个JS Bin示例(运行它,不要忘记控制台):

    +1为了给我指明正确的方向,让我们做更多的工作来得到答案。请告诉我您的情况。如果你被困在某个地方,我也会尝试在我这边建立这个项目。这是一个很好的例子,相信很有可能。你能更好地解释一下“监控脚本”的含义吗?thanksjQuery支持同一事件的多个处理程序,因此,如果您想知道某人何时单击某个锚点(例如),您可以将代码添加到MonitorScript中(请参见上面我编辑的答案)。我相信这正是本文所说的,请包装对现有javascript代码的其他调用(不在您的控制范围内)加载到webbrowser代码中。i、 e.对于页面中的每个javascript函数,向您的侦听器注入一个调用(该调用将在MonitorScript.js中定义)。让我看看能不能帮你把这些代码整理好。本周我不在,但这将是一个值得深思的好任务。将javascript附加到事件的问题是,它无法检测使用函数(如
    setTimeout
    )执行的javascript的执行。此外,如果单击没有触发javascript调用呢?无益。无论何时,我都需要检测javascript函数的执行情况,无论是在事件处理程序中调用、由超时触发还是以其他方式。目前我没有太多时间来测试这一点,您能否解释一下,我如何通过
    window.external
    在网页中检测对特定js函数的调用?一个小的代码示例也会得到很好的更新,我添加了相关的JS,希望能够完成解决方案。这正是我所需要的,非常高兴能够奖励奖金并解决这个问题,谢谢!没问题,仅供参考,我玩过Function.prototype.call,认为这样做可以,但除非调用call(),否则无法使其工作。
    WebBrowser.Head
    ?这是一个示例,您的意思是
    WebBrowser.Document.GetElementsByTagName(“head”)[0]
    private void addScript(HtmlElement head, string scriptSource) 
    { 
    HtmlElement lhe_script = head.Document.CreateElement("script"); 
    IHTMLScriptElement script = (IHTMLScriptElement)lhe_script.DomElement; 
    script.src = scriptSource;
    head.AppendChild(lhe_script);            
    } 
    
    addScript(WebBrowser.Head, @"InjectMonitor.js");
    
    function augment(withFn) {
        var name, fn;
        for (name in window) {
            fn = window[name];
            if (typeof fn === 'function') {
                window[name] = (function(name, fn) {
                    var args = arguments;
                    return function() {
                        withFn.apply(this, args);
                        fn.apply(this, arguments);
    
                    };
                })(name, fn);
            }
        }
    }
    
    augment(function(name, fn) {
        console.log("calling " + name, fn);
    
        // window.external.yourC#method
    });