Android WebView中JavaScript提示框无法正常工作

100
在我的应用程序中,我正在使用WebView,并且在其中我正在使用JavaScript alert()方法,但它不起作用,没有弹出窗口出现。
在我的清单文件中,我已经添加了:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

还有在活动文件中我已经添加了

mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl("file:///android_asset/demo.html");

在布局XML文件中我添加了:

<WebView 
    android:id="@+id/webview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/>

有没有任何线索可以启用WebView中完整的JavaScript


更新

感谢mark,html文件中的alert()方法现在可以使用了 :)。

现在在WebView中存在两个问题:
1:我在加载到WebView中的html文件中使用了<textarea>,并试图使用印地语字体在其中编写,但当我尝试编写印地文本时,它会显示为符号(类似于[]的矩形符号)。在桌面上使用Firefox浏览器进行相同操作时,一切正常。有没有线索可以在WebView中支持多种语言的<textarea>

2:当我单击提交并尝试打开另一个JavaScript中的alert()方法中的文本值时,它不起作用,这是否意味着即使使用了WebChromeClient,它也仅适用于当前加载的HTML页面,而不是该页面调用的javascripts


6
应该使用"JavaScript"而不是"Java Script"、"java-script"或"Java script"(这些都出现在你原来的问题中)。我已经为你纠正过了。 - T.J. Crowder
3
@T.J.Crowder 我敢说它应该被称为 Javascript - Kris Selbekk
7
@KrisSelbekk: 不是的 :-) "JavaScript" 是Oracle注册商标(必须感谢合并和收购),并且被(经过允许)Mozilla用于他们的实现。在这两种情况下,“JavaScript”的“S”都要大写。这是该名称的唯一规范形式。当然,该语言的另一个名称是ECMAScript(或ES),但除了在谈论ES5时几乎没有人使用它。 - T.J. Crowder
6个回答

135

正如其他人所指出的,设置WebChromeClient是必要的才能使alert()工作。只需设置默认的WebChromeClient即可:

mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebChromeClient(new WebChromeClient());

感谢下面所有的评论,包括John Smith指出需要启用JavaScript。


是的,但大多数情况下,您希望调整WebChromeClient的事件... - Radu Simionescu
10
我最终通过在“mWebView.setWebChromeClient(new WebChromeClient())”之前添加“mWebView.getSettings().setJavaScriptEnabled(true);”来使其工作。 - John Smith Optional
2
不要忘记添加 webview.getSettings().setJavaScriptEnabled(true); - Jemshit Iskenderov

97

查看此链接,并阅读最后一条评论,您需要使用WebChromeClient来达成你的目的。


8
webView.setWebChromeClient(new WebChromeClient() {@Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { return super.onJsAlert(view, url, message, result); } }); - nurnachman
你的评论对我很有帮助,就像下面Nikhil的回答一样。 - Vamsi Challa
运行得很好。但是...... WebClient 有什么优势比 WebChromeClient 更好吗? - Josh
3
或许这是一个愚蠢的问题,但还是要问一下:为什么要重写一个方法,只是为了调用具有相同参数的父类方法? - Dmitry Andrievsky
1
不要忘记添加 webview.getSettings().setJavaScriptEnabled(true); - Jemshit Iskenderov
显示剩余3条评论

27
webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
        return super.onJsAlert(view, url, message, result);
    }
});

这个很好用,但是当我从JavaScript调用prompt时,它不会显示提示文本,而是说:“https://...的页面说:”,完全破坏了嵌入应用程序中的WebView的沉浸感。 - Michael

5
以下代码将有效:
private WebView mWebView;
final Activity activity = this;

// private Button b;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mWebView = (WebView) findViewById(R.id.webview);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.getSettings().setDomStorageEnabled(true);
    mWebView.setWebChromeClient(new WebChromeClient() {
        public void onProgressChanged(WebView view, int progress) {
            activity.setProgress(progress * 1000);
        }
    });

    mWebView.loadUrl("file:///android_asset/raw/NewFile1.html");
}

0

你可以试试这个,对我有效

WebView wb_previewSurvey=new WebView(this); 


       wb_previewSurvey.setWebChromeClient(new WebChromeClient() {
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            //Required functionality here
            return super.onJsAlert(view, url, message, result);
        }

    });

0
如果您希望将URL隐藏不让用户看到,可以像下面这样显示一个AlertDialog。
myWebView.setWebChromeClient(new WebChromeClient() {

            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                Log.d(TAG, "onJsAlert url: " + url + "; message: " + message);
                AlertDialog.Builder builder = new AlertDialog.Builder(
                        mContext);
                builder.setMessage(message)
                        .setNeutralButton("OK", new OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int arg1) {
                                dialog.dismiss();
                            }
                        }).show();
                result.cancel();
                return true;
            }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接