CefSharp _JS-C#互相调用学习笔记

一 其他

1 通过指定uri指定body (KnowledgeBase项目)
 public static void RegisterTestResources(IWebBrowser browser)
        {
            var factory = browser.ResourceHandlerFactory;

            if (factory != null)
            {
                const string responseBody =
                    "<html>"
                    + "<body><h1>About</h1>"
                    + "<p>This sample application implements a <b>ResourceHandler</b> "
                    + "which can be used to fullfil custom network requests as explained here:"
                    + "<a href=\"http://www.codeproject.com/Articles/881315/Display-HTML-in-WPF-and-CefSharp-Tutorial-Part 2\">http://www.codeproject.com/Articles/881315/Display-HTML-in-WPF-and-CefSharp-Tutorial-Part 2</a>"
                    + ".</p>"
					+ "<hr/><p>This sample is based on CefSharp <b>39.0.0</b></p>"
                    + "<hr/>"
                    + "<p>See also CefSharp on GitHub: <a href=\"https://github.com/cefsharp\">https://github.com/cefsharp</a><br/>"
                    + "<p>and Cef at Google: <a href=\"https://code.google.com/p/chromiumembedded/wiki/GeneralUsage#Request_Handling\">https://code.google.com/p/chromiumembedded/wiki/GeneralUsage#Request_Handling</a>"
                    + "</body></html>";

                factory.RegisterHandler(TestResourceUrl, ResourceHandler.FromString(responseBody));

                const string unicodeResponseBody = "<html><body>整体满意度</body></html>";
                factory.RegisterHandler(TestUnicodeResourceUrl, ResourceHandler.FromString(unicodeResponseBody));
            }
        }
2 通过指定Uri展示markdown页面(MarkdownSharp)
3 Brower与frame关系
            var frame= Browser.GetFocusedFrame();
            var frame1 = Browser.GetMainFrame();

二 C#调用JS

1 JS必须在V8Context下执行

可以通过一下代码来判断:

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);
  }
}
2 调用Void JS
 const string script = "document.addEventListener('DOMContentLoaded', function(){ alert('DomLoaded'); });";
 frame.ExecuteJavaScriptAsync(script);
3 调用带返回值的JS

browser.EvaluateScriptAsync(script)

frame.EvaluateScriptAsync(script);

browser.EvaluateScriptAsPromiseAsync(script);

//An extension method that evaluates JavaScript against the main frame.
Task<JavascriptResponse> response = await browser.EvaluateScriptAsync(script);
//Evaluate javascript directly against a frame
Task<JavascriptResponse> response = await frame.EvaluateScriptAsync(script);

//An extension method that evaluates Javascript Promise against the main frame.
//Uses Promise.resolve to return the script execution into a promise regardless of the return type
//This method differs from EvaluateScriptAsync in that your script **must return** a value
//Examples below
Task<JavascriptResponse> response = await browser.EvaluateScriptAsPromiseAsync(script);
4 JS-IIFE
(function () {
  statements
})();
  1. 第一个是匿名功能,其词汇范围封闭在分组操作员内。这可以防止在 IIFE 成语中访问变量,并污染全球范围。()
  2. 第二部分创建立即调用的函数表达,通过该表达式,JavaScript 引擎将直接解释该函数。()
5 JS- Promise

Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。

1、对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:

  • pending: 初始状态,不是成功或失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。

6 JS setTimeout

setTimeout() 是属于 window 的方法,该方法用于在指定的毫秒数后调用函数或计算表达式。

语法格式可以是以下两种:

setTimeout(要执行的代码, 等待的毫秒数)
setTimeout(JavaScript 函数, 等待的毫秒数)
7 JS bind

给函数传参,第一个参数是对象,剩下的是参数。

img

obj.myFun.call(db,'成都','上海');     // 德玛 年龄 99  来自 成都去往上海
obj.myFun.apply(db,['成都','上海']);      // 德玛 年龄 99  来自 成都去往上海  
obj.myFun.bind(db,'成都','上海')();       // 德玛 年龄 99  来自 成都去往上海
obj.myFun.bind(db,['成都','上海'])();   // 德玛 年龄 99  来自 成都, 上海去往 undefined
8 JS Array.from

**Array.from()** 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

三 JS调用C#

1 总结
  1. 1通过Native Chromium IPC (进程间通讯)在浏览器进程和渲染进程传递消息

    1.2 返回值是简单对象,类, 结构体,只有属性的副本被转到JS中

    1.3 方法名被转换成开头小写,CamelCase格式

2 在JS中绑定一个异步对象

CefSharp.BindObjectAsync 提供一个Promise JS 绑定,按名称绑定

  1. 1步骤

    1 创建一个想要暴露给JS的类

    2 创建一个类型实例并用JavaScriptObjectRepository绑定(两种方式,第一种立即注册,第二种在使用的时候才注册)

    //For async object registration (equivalent to the old RegisterAsyncJsObject)
    Browser.JavascriptObjectRepository.Register("boundAsync", new BoundObject(), BindingOptions.DefaultBinder);
    //注册成功通知
    Browser.JavascriptObjectRepository.ObjectBoundInJavascript += (sender, e) =>
    {
    var name = e.ObjectName;

     		Debug.WriteLine($"Object {e.ObjectName} was bound successfully.");
     	};
    

    3 调用 CefSharp.BindObjectAsync 并用一个名称去注册

      private async void Button_Click_13(object sender, RoutedEventArgs e)
            {
                const string script = @"(async function()
    {
    			await CefSharp.BindObjectAsync('boundAsync');
    
    	//The default is to camel case method names (the first letter of the method name is changed to lowercase)
    			boundAsync.add(16, 2).then(function(actualResult)
    	{
    				const expectedResult = 18;
    				alert(actualResult);
    			});
    		})();";
                var javascriptResponse = await Browser.EvaluateScriptAsync(script);
                dynamic result = javascriptResponse.Result;
    		}
    

    4 只可以绑定方法,如果想绑定属性,可以用get,set方法

    四 Demo

https://github.com/tiancai4652/CefSahrp_Test

posted @ 2021-06-24 17:44  猝不及防  阅读(1611)  评论(0编辑  收藏  举报