CefSharp执行JavaScript

23

我希望能够在Windows Forms中使用CefSharp执行JavaScript代码,但它没有起作用。以下是我的代码,消息“test”没有显示。我错过了什么吗?

var browser = new ChromiumWebBrowser("http://localhost:50056/simple.aspx");
browser.Name = "Simple Page";
browser.Dock = DockStyle.Fill;            
this.Controls.Add(browser);
browser.ExecuteScriptAsync("alert('test');");

我使用Nuget安装cefsharp,版本为41.0.0。 - Pei-Chun Tsai
2个回答

37

在执行JavaScript之前,您必须等待浏览器充分加载。在OnFrameLoadStart中开始尝试访问DOM是很诱人的,因为V8Context将已经创建并且您将能够执行脚本,但是DOM尚未完成加载。如果您需要在最早可能的时候访问DOM,请订阅DOMContentLoaded事件。

以下是一些执行JavaScript的示例。

browser.RenderProcessMessageHandler = new RenderProcessMessageHandler();

public class RenderProcessMessageHandler : IRenderProcessMessageHandler
{
  // Wait for the underlying JavaScript Context to be created. This is only called for the main frame.
  // If the page has no JavaScript, no context will be created.
  void IRenderProcessMessageHandler.OnContextCreated(IWebBrowser browserControl, IBrowser browser, IFrame frame)
  {
    const string script = "document.addEventListener('DOMContentLoaded', function(){ alert('DomLoaded'); });";

    frame.ExecuteJavaScriptAsync(script);
  }
}

//Wait for the page to finish loading (all resources will have been loaded, rendering is likely still happening)
browser.LoadingStateChanged += (sender, args) =>
{
  //Wait for the Page to finish loading
  if (args.IsLoading == false)
  {
    browser.ExecuteJavaScriptAsync("alert('All Resources Have Loaded');");
  }
}

//Wait for the MainFrame to finish loading
browser.FrameLoadEnd += (sender, args) =>
{
  //Wait for the MainFrame to finish loading
  if(args.Frame.IsMain)
  {
    args.Frame.ExecuteJavaScriptAsync("alert('MainFrame finished loading');");
  }
};

4
下一个主要版本的CefSharp将会抛出异常,以自我说明为目的,而不是默默地什么也不做,这将影响您原始代码的执行。 - amaitland
2
更多细节请参见 https://github.com/cefsharp/CefSharp/wiki/Frequently-asked-questions#CallJS - amaitland
1
请查看最新的内容,请访问https://github.com/cefsharp/CefSharp/wiki/General-Usage#when-can-i-start-executing-javascript - amaitland
1
这里还有一个非常清晰的视频 -> https://archive.org/details/ExecutingJavaScriptFromThe.NETSideUsingCefSharp_201711 - JsAndDotNet

2

在调用存在于HTML中的JavaScript函数并传递输入参数的情况下,可以在MainWindow构造函数中简单地使用Browser.LoadingStateChanged事件来确保启动加载。该事件将在Browser_Loaded之后被调用,其中声明了HTML文件。以下是代码示例:

public MainWindow()
        {
            InitializeComponent();

            //Wait for the page to finish loading (all resources will have been loaded, rendering is likely still happening)
            Browser.LoadingStateChanged += (sender, args) =>
            {
                //Wait for the Page to finish loading
                if (args.IsLoading == false)
                {
                    Browser.ExecuteScriptAsync("JavaScripFunctionName1", new object[] { arg1, arg2});
                }
            };
        }

private void Browser_Loaded(object sender, RoutedEventArgs e)
        {
            Browser.LoadHtml(File.ReadAllText(GetFilePath("YourHTMLFileName.html")));
        }

然而,如果你想执行JavaScript代码并获取结果,应该使用:

var result = await Browser.EvaluateScriptAsync("JavaScripFunctionName2", new object[] { });
MessageBox.Show(result.Result.ToString());

在 HTML 中:
<html>
<body>
    <script>
        function JavaScripFunctionName1(arg1, arg2)
        {
            // something here
        }

        function JavaScripFunctionName2()
        {
            // something here
            return result;
        }        
    </script>
</body>
</html>

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