![](/img/trans.png)
[英]How to call JavaScript from C# in hybridwebview in Xamarin PCL?
[英]Xamarin HybridWebView calling JS function from C#
我正在尝试获得一个 HybridWebView,其中 JS 和 C# 代码可以相互通信。 我遵循了官方文档,从 JS 调用 C# 代码工作正常。 但是我也需要另一种方式,这在提到的教程中没有指导。 这是我有多远:
在我的 HybridWebView 控件中,我添加了以下几行:
public event EventHandler CallJavascript;
public void InvokeJS()
{
if(CallJavascript != null)
{
CallJavascript(this, EventArgs.Empty);
}
}
在我的自定义渲染器中,我在OnElementChanged()
方法中添加了 CallJavascript 方法和它
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var webView = new Android.Webkit.WebView(_context);
webView.Settings.JavaScriptEnabled = true;
webView.SetWebViewClient(new JavascriptWebViewClient($"javascript: {JavascriptFunction}"));
SetNativeControl(webView);
}
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
e.OldElement.CallJavascript += OnElementCallJavascript;
}
if (e.NewElement != null)
{
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
Control.LoadUrl($"file:///android_asset/Content/{Element.Uri}");
e.NewElement.CallJavascript += OnElementCallJavascript;
}
}
private void OnElementCallJavascript(object sender, EventArgs e)
{
var webView = new Android.Webkit.WebView(_context);
Device.BeginInvokeOnMainThread(() =>
{
webView.EvaluateJavascript("javascript:increaseCount();", null);
});
}
但是,我在 OnElementCallJavascript 中获得的 webview 不是我从中调用方法的 webview,因此没有评估 javascript。 任何人都知道我如何实现这一目标?
问题是我正在创建一个新的Android.WebKit.WebView
。 像这样使用它解决了问题:
Device.BeginInvokeOnMainThread(() =>
{
Control.EvaluateJavascript("javascript:increaseCount();", null);
});
直接/直接使用这样的东西怎么样?
e.NewElement.CallJavascript += (sender, args) =>
{
Control.EvaluateJavascript("javascript:increaseCount();", null);
};
在 Xamarin.Forms 中的 HybridWebView 中定义可绑定布局和操作:
public class HybridWebView : WebView
{
Action<string> action;
public static BindableProperty EvaluateJavascriptProperty =
BindableProperty.Create(nameof(EvaluateJavascript), typeof(Func<string, Task<string>>), typeof(HybridWebView), null, BindingMode.OneWayToSource);
public Func<string, Task<string>> EvaluateJavascript
{
get { return (Func<string, Task<string>>)GetValue(EvaluateJavascriptProperty); }
set { SetValue(EvaluateJavascriptProperty, value); }
}
public void RegisterAction(Action<string> callback)
{
action = callback;
}
public void Cleanup()
{
action = null;
}
public void InvokeAction(string key)
{
if (action == null)
{
return;
}
action.Invoke(key);
}
}
在您的页面中调用 EvaluateJavacript:
await webview.EvaluateJavascript("javascript:increaseCount();");
在您的渲染器中:
private HybridWebView xfWebView;
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var webView = new Android.Webkit.WebView(_context);
webView.Settings.JavaScriptEnabled = true;
webView.SetWebViewClient(new JavascriptWebViewClient($"javascript: {JavascriptFunction}"));
SetNativeControl(webView);
}
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
e.OldElement.CallJavascript += OnElementCallJavascript;
}
if (e.NewElement != null)
{
xfWebView = e.NewElement;
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
if (xfWebView != null)
{
xfWebView.EvaluateJavascript = async (js) =>
{
var reset = new ManualResetEvent(false);
var response = string.Empty;
Device.BeginInvokeOnMainThread(() =>
{
Control?.EvaluateJavascript(js, new JavascriptCallback((r) => { response = r; reset.Set(); }));
});
await Task.Run(() => { reset.WaitOne(); });
return response;
};
}
Control.LoadUrl($"file:///android_asset/Content/{Element.Uri}");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.