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
})();
- 第一个是匿名功能,其词汇范围封闭在
分组操作员
内。这可以防止在 IIFE 成语中访问变量,并污染全球范围。()
- 第二部分创建立即调用的函数表达,通过该表达式,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
给函数传参,第一个参数是对象,剩下的是参数。
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通过Native Chromium IPC (进程间通讯)在浏览器进程和渲染进程传递消息
1.2 返回值是简单对象,类, 结构体,只有属性的副本被转到JS中
1.3 方法名被转换成开头小写,CamelCase格式
2 在JS中绑定一个异步对象
CefSharp.BindObjectAsync 提供一个Promise JS 绑定,按名称绑定
-
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