1. Background
Recently, I used CefSharp to load H5 pages in a project , some of which business logic needs to call Js functions, and Js will also call some native functions:
Here we use the official demo code to add and modify, the modified code is here: DevWiki/CefSharp.MinimalExample - CefSharp.MinimalExample - DevWiki Gitea
2. Js calls Native function
According to the official instructions, General Usage · cefsharp/CefSharp Wiki , divided into two steps:
- Set Enable Js
- Register a Class for Js to call
//设置 启用 Js
Browser.BrowserSettings.Javascript = CefState.Enabled;
Browser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;
//注册一个 Class 给Js调用
Browser.JavascriptObjectRepository.Register("script", new Script(), false, BindingOptions.DefaultBinder);
public class Script
{
public string GetWindowName()
{
return "MainWindow";
}
public void PrintLog(string log)
{
Console.WriteLine($"H5 log:{
log}");
}
}
For the convenience of testing, set the Browser to respond to F12 to open DevTool:
Browser.WpfKeyboardHandler = new WebBrowserWpfKeyboardHandler(Browser);
public class WebBrowserWpfKeyboardHandler : WpfImeKeyboardHandler
{
public WebBrowserWpfKeyboardHandler(ChromiumWebBrowser owner) : base(owner)
{
}
public override void HandleKeyPress(KeyEventArgs e)
{
base.HandleKeyPress(e);
if (e.Key == Key.F12)
{
owner.ShowDevTools();
}
}
}
After running, press F12, open the console input: script.
see the prompt:
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-kwCxn2xc-1670731074318)(api/images/iGKYxVbEAHsw/202212102324686.png)]
You can see the functions we registered, so that Js can call native functions.
Another way is to register dynamically, as follows:
Browser.JavascriptObjectRepository.ResolveObject += JavascriptObjectRepositoryOnResolveObject;
private void JavascriptObjectRepositoryOnResolveObject(object sender, JavascriptBindingEventArgs e)
{
var repo = e.ObjectRepository;
if (e.ObjectName == "script")
{
repo.Register("script", new Script(), isAsync: true, options: BindingOptions.DefaultBinder);
}
}
3. WPF calls Js function
General web pages have alert()
this function, that is, a dialog window pops up, press F12 to open devtool, switch to the console, enter the function and press Enter, the result is as follows:
You can also pass in a parameter to display a prompt message: alert("test")
:
So how to call it in the project? According to the official documentation: CefSharp Chinese Help Document cefsharp/CefSharp Wiki
Browser.MainFrame.ExecuteJavaScriptAsync("alert()");
// 或者
Browser.ExecuteScriptAsync("alert()");
If you need to pass in parameters, you can use string interpolation directly:
Browser.MainFrame.ExecuteJavaScriptAsync($"alert({message})");
// 或者
Browser.ExecuteScriptAsync($"alert({message})");
Or use the method of passing in parameters:
object[] args = new object[2];
args[0] = JsArgs1Tb.Text;
args[1] = JsArgs2Tb.Text;
Browser.ExecuteScriptAsync("alert()", args);
If you install the above code to call the Js function with parameters, it will not actually execute as you expected!
If you install the above code to call the Js function with parameters, it will not actually execute as you expected!
If you install the above code to call the Js function with parameters, it will not actually execute as you expected!
Say important things three times!
Why do the above problems occur? Here we need to look at what the function with parameters does?
public static void ExecuteScriptAsync(
this IBrowser browser,
string methodName,
params object[] args)
{
string javascriptMethodWithArgs = WebBrowserExtensions.GetScriptForJavascriptMethodWithArgs(methodName, args);
browser.ExecuteScriptAsync(javascriptMethodWithArgs);
}
In this code, the function name and function parameters will be spliced first:
WebBrowserExtensions.GetScriptForJavascriptMethodWithArgs(methodName, args);
Here we test alert
the concatenation of functions and parameters:
The result after splicing will be brought automatically ()
, remove the brackets and test again:
The pop-up window is as follows:
The content that we fill in appears in the prompt.
3. Summary
Use Js to call native functions:
- WebBrowser settings enable Js function
- Register a class for Js to call
Use native to call js function:
- If it is a function without parameters, the function name needs to bring: ()
- If it is a function with parameters, either it is spliced into a complete function + parameters when calling, or it is used when calling
WebBrowserExtensions.GetScriptForJavascriptMethodWithArgs
and the function only writes the name without parentheses.
The above code is in: DevWiki/CefSharp.MinimalExample - CefSharp.MinimalExample - DevWiki Gitea