在我的项目中,我有一个WebView
可以加载页面(HTML)。
我想更改所有图像并在用户单击任何图像时显示祝酒词。
所以我要添加调用Java函数的javascript代码:
// code is inside onPageFinished(..) function
JavaScriptInterface jsInterface = new JavaScriptInterface(activity);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(jsInterface, "JSInterface");
webView.evaluateJavascript(
"var imgs = document.getElementsByTagName('img');" +
"for (var i = 0; i < imgs.length; i++) {" +
"imgs[i].src = 'file:///android_asset/rules_images_placeholder.png';" +
"imgs[i].addEventListener('click', function() {" +
"window.JSInterface.showToast(); " + // <-- isn't called: see logs
"});" +
"} " +
"window.JSInterface.showToast();" // <-- is called
, null);
JavaScriptInterface类:
public class JavaScriptInterface {
private Activity activity;
public JavaScriptInterface(Activity activity) {
this.activity = activity;
}
@JavascriptInterface
public void showToast() {
Toast.makeText(activity, "Toast message", Toast.LENGTH_SHORT).show();
}
}
showToast()
应该在什么时候调用
页面已完成加载
用户点击了图片
问题:showToast()
仅被调用一次-页面完成加载后。
当用户单击图像时,不会调用showToast()
,而是显示以下日志:
未捕获的TypeError:无法读取未定义的属性'showToast', 来源:
问题
如何在点击图片时调用showToast()
?
答案 0 :(得分:3)
删除评估Java方法,并使用loadUrl。试试下面的代码对我有用:-
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
}
@Override
public void onPageFinished(final WebView view, String url) {
Log.e("checking", "MYmsg");
webView.loadUrl("javascript: var imgs = document.getElementsByTagName('img');" +
"for (var i = 0; i < imgs.length; i++) {" +
"imgs[i].addEventListener('click', function() {" +
"window.CallToAnAndroidFunction.showToast(); " +
"});" +
"} " );
}
});
webView.addJavascriptInterface(new WebAppInterface(Main2Activity.this),
"CallToAnAndroidFunction");
接口:-
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
@JavascriptInterface
public void showToast() {
Toast.makeText(mContext, "Toast message", Toast.LENGTH_SHORT).show();
}
}
答案 1 :(得分:2)
我不确定为什么,但是您可以通过在加载HTML内容之前添加JavaScript接口来解决此问题。
jsInterface = new JavaScriptInterface(activity);
fragmentWebView.getSettings().setJavaScriptEnabled(true);
fragmentWebView.getSettings().setDomStorageEnabled(true);
fragmentWebView.addJavascriptInterface(jsInterface, "JSInterface");
fragmentWebView.loadDataWithBaseURL("file:///android_asset/", fullHtml, "text/html", "utf-8", null);
fragmentWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
view.loadUrl(
"javascript:var imgs = document.getElementsByTagName('img');" +
"for (var i = 0; i < imgs.length; i++) {" +
"imgs[i].src = 'file:///android_asset/rules_images_placeholder.png';" +
"imgs[i].addEventListener('click', function(e) {" +
"window.JSInterface.showToast(); " +
"});" +
"}" +
"console.log(window.JSInterface);" +
"window.JSInterface.showToast(); ");
}
});
答案 2 :(得分:0)
好像您没有<img>
标签
尝试先添加它们并检查
Android功能
WebView webView= findViewById(R.id.webview);
JavaScriptInterface jsInterface = new JavaScriptInterface(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(jsInterface, "JSInterface");
webView.evaluateJavascript(
"document.write('<img>');" +
"document.write('<img>');\n"+
"var x = document.getElementsByTagName('IMG');" +
"console.log(x.length);"+
"for (var i = 0; i < x.length; i++) {" +
"x[i].src = 'https://www.imagemagick.org/Usage/images/badge_overlay.png';" +
"x[i].addEventListener('click', function() {" +
"window.JSInterface.showToast(); " + // <-- now calling :)
"});" +
"} " +
"window.JSInterface.showToast();" // <-- is called
, null);
,或者您可以先从资产中加载html内容。与webView.loadUrl();
答案 3 :(得分:0)
您无需等待dom级图像的出现。
string code = `
document.addEventListener("click",(e)=> {
if(e.target instanceof Image){
window.JSInterface.showToast();
}
});`
webView.evaluateJavascript(code, null);
在此示例中,我使用了字符串文字=> https://stackoverflow.com/a/50155171/5138198
答案 4 :(得分:0)
您是否尝试过将Javascript函数实际调用Java并将其放置在与Webview相关的html页面中。将其放在标头中,因此它将在以后发生click事件时确定存在,并且不会在对函数进行任何评估后消失,就像您现在遇到的情况一样。
<script type="text/javascript">
function showAndroidToast(toast) {
JSInterface.showToast(toast);
}
</script>
我发现类似情况的来源总是引用单独的html: