将带有 javascript 的一些文本从 Xamarin.Forms 传递到 WebView
Pass some text with javascript into WebView from Xamarin.Forms
我尝试从 xamarin.forms 向 webView 控件发送一些文本。有很多解决方案,我几乎都试过了......;-)
所以实际上它们工作得很好,但我总是要单击 html 文件上的一个按钮,我将其加载到此 webView 中,这样我就可以将一些文本传递到 html 文件中。但我想在不单击此按钮的情况下传递文本。当 webView 加载时,文本应该在那里。
这里是一些代码:
在 xaml.cs 我加载 WebView:
protected override void OnAppearing()
{
base.OnAppearing();
webViewElement.Source = new HtmlWebViewSource();
webViewElement.Source = DependencyService.Get<IBaseUrl>().Get();
webViewElement.RegisterAction(ExecuteActionFromJavascript);
ExecuteSetFromJavascript();
}
然后使用 ExecuteSetFromJavascript() 调用 html 文件中的一个函数:
private async void ExecuteSetFromJavascript()
{
var result = "Hello";
if (result != null)
{
var test = await webViewElement.EvaluateJavaScriptAsync($"updatetextonwebview('{result}')");
}
}
这是 html 文件中的函数:
function updatetextonwebview(text) {
alert(text);
// document.getElementById("content").innerHTML = text;
}
所以现在页面应该在调用 updatetextonwebview 时提醒 "Hello"。
但这并没有成功。也许我调用这个函数时 html 页面还没有准备好!
有人知道我如何找到我的解决方案吗?
提前致谢...
您想要的是 HybridWebView。这意味着它既可以接收也可以发送数据。
我发现您提供的代码存在很多不一致和问题 - 为什么要在 OnAppearing 中配置 WebView,为什么要设置两次源,等等。
由于提供的代码还不够,而且充满了问题和问题 - 与其试图找出哪里出了问题,不如按照官方指南创建一个 HybridWebView 来自 Microsoft - Customizing a WebView.
这很有效,而且您在 GitHub 中有可用的最终解决方案 here。
如果您还有其他问题,请随时提出,但我觉得该指南非常简单明了。
我现在的解决方案是:在 HybridWebView 我添加了一个 属性
using System;
using Xamarin.Forms;
namespace CustomRenderer
{
public class HybridWebView : WebView
{
Action<string> action;
public static readonly BindableProperty UriProperty = BindableProperty.Create(
propertyName: "Uri",
returnType: typeof(string),
declaringType: typeof(HybridWebView),
defaultValue: default(string));
public static BindableProperty QuestionProperty = BindableProperty.Create(
propertyName: "Question",
returnType: typeof(string),
declaringType: typeof(HybridWebView),
defaultValue: default(string));
public static BindableProperty AnswerProperty = BindableProperty.Create(
propertyName: "Answer",
returnType: typeof(string),
declaringType: typeof(HybridWebView),
defaultValue: default(string));
public string Uri
{
get { return (string)GetValue(UriProperty); }
set { SetValue(UriProperty, value); }
}
public string Question
{
get { return (string)GetValue(QuestionProperty); }
set { SetValue(QuestionProperty, value); }
}
public string Answer
{
get { return (string)GetValue(AnswerProperty); }
set { SetValue(AnswerProperty, value); }
}
public void RegisterAction(Action<string> callback)
{
action = callback;
}
public void Cleanup()
{
action = null;
}
public void InvokeAction(string data)
{
if (action == null || data == null)
{
return;
}
action.Invoke(data);
}
}
}
我可以在 JavaScriptWebViewClient 中访问它,在 OnPageFinished 上我可以将数据提交到网页。
public class JavascriptWebViewClient : FormsWebViewClient
{
string _javascript;
string _question;
private string _answer;
public JavascriptWebViewClient(HybridWebViewRenderer renderer, string javascript, string question, string answer) : base(renderer)
{
_javascript = javascript;
_answer = answer;
_question = question;
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
view.EvaluateJavascript($"factorial({_question}, {_answer})", null);
view.EvaluateJavascript(_javascript, null);
}
}
我尝试从 xamarin.forms 向 webView 控件发送一些文本。有很多解决方案,我几乎都试过了......;-)
所以实际上它们工作得很好,但我总是要单击 html 文件上的一个按钮,我将其加载到此 webView 中,这样我就可以将一些文本传递到 html 文件中。但我想在不单击此按钮的情况下传递文本。当 webView 加载时,文本应该在那里。
这里是一些代码:
在 xaml.cs 我加载 WebView:
protected override void OnAppearing()
{
base.OnAppearing();
webViewElement.Source = new HtmlWebViewSource();
webViewElement.Source = DependencyService.Get<IBaseUrl>().Get();
webViewElement.RegisterAction(ExecuteActionFromJavascript);
ExecuteSetFromJavascript();
}
然后使用 ExecuteSetFromJavascript() 调用 html 文件中的一个函数:
private async void ExecuteSetFromJavascript()
{
var result = "Hello";
if (result != null)
{
var test = await webViewElement.EvaluateJavaScriptAsync($"updatetextonwebview('{result}')");
}
}
这是 html 文件中的函数:
function updatetextonwebview(text) {
alert(text);
// document.getElementById("content").innerHTML = text;
}
所以现在页面应该在调用 updatetextonwebview 时提醒 "Hello"。
但这并没有成功。也许我调用这个函数时 html 页面还没有准备好!
有人知道我如何找到我的解决方案吗?
提前致谢...
您想要的是 HybridWebView。这意味着它既可以接收也可以发送数据。
我发现您提供的代码存在很多不一致和问题 - 为什么要在 OnAppearing 中配置 WebView,为什么要设置两次源,等等。
由于提供的代码还不够,而且充满了问题和问题 - 与其试图找出哪里出了问题,不如按照官方指南创建一个 HybridWebView 来自 Microsoft - Customizing a WebView.
这很有效,而且您在 GitHub 中有可用的最终解决方案 here。
如果您还有其他问题,请随时提出,但我觉得该指南非常简单明了。
我现在的解决方案是:在 HybridWebView 我添加了一个 属性
using System;
using Xamarin.Forms;
namespace CustomRenderer
{
public class HybridWebView : WebView
{
Action<string> action;
public static readonly BindableProperty UriProperty = BindableProperty.Create(
propertyName: "Uri",
returnType: typeof(string),
declaringType: typeof(HybridWebView),
defaultValue: default(string));
public static BindableProperty QuestionProperty = BindableProperty.Create(
propertyName: "Question",
returnType: typeof(string),
declaringType: typeof(HybridWebView),
defaultValue: default(string));
public static BindableProperty AnswerProperty = BindableProperty.Create(
propertyName: "Answer",
returnType: typeof(string),
declaringType: typeof(HybridWebView),
defaultValue: default(string));
public string Uri
{
get { return (string)GetValue(UriProperty); }
set { SetValue(UriProperty, value); }
}
public string Question
{
get { return (string)GetValue(QuestionProperty); }
set { SetValue(QuestionProperty, value); }
}
public string Answer
{
get { return (string)GetValue(AnswerProperty); }
set { SetValue(AnswerProperty, value); }
}
public void RegisterAction(Action<string> callback)
{
action = callback;
}
public void Cleanup()
{
action = null;
}
public void InvokeAction(string data)
{
if (action == null || data == null)
{
return;
}
action.Invoke(data);
}
}
}
我可以在 JavaScriptWebViewClient 中访问它,在 OnPageFinished 上我可以将数据提交到网页。
public class JavascriptWebViewClient : FormsWebViewClient
{
string _javascript;
string _question;
private string _answer;
public JavascriptWebViewClient(HybridWebViewRenderer renderer, string javascript, string question, string answer) : base(renderer)
{
_javascript = javascript;
_answer = answer;
_question = question;
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
view.EvaluateJavascript($"factorial({_question}, {_answer})", null);
view.EvaluateJavascript(_javascript, null);
}
}