【问题标题】:webview don't display javascript windows.open()webview 不显示 javascript windows.open()
【发布时间】:2012-02-05 08:13:07
【问题描述】:

我有一个WebView,我在其中显示我无法控制的网页内容。内容显示正常,但有链接会产生一个弹出窗口。执行此操作的 javascript 函数如下所示:

function getEntry(id) {
var win = window.open('', 'Booking',
'resizable=yes,scrollbars=yes,status=no,width=500,height=400');
win.document.location = '/some/url/1-' + id ;
}

我不能轻易改变这一点,如果负责我下载的页面的人会改变它,我想我的应用程序会惨遭失败......

我在活动中的WebView 设置如下所示:

    _webview = new WebView(this);
    setContentView(_webview);

    final Activity activity = this;
    _chromeClient = new MyChromeClient();

    _webview.setWebChromeClient(_chromeClient);

    //I experimented with changing user agent, in case that would have any effect, it didn't...
    _webview.getSettings().setUserAgentString("Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1");

    _webview.setWebViewClient(new MyWebViewClient());
    _webview.getSettings().setJavaScriptEnabled(true);
    _webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    _webview.getSettings().setSupportZoom(true);
    _webview.getSettings().setBuiltInZoomControls(true);
    _webview.getSettings().setDomStorageEnabled(true);
    //Cache settings...
    _webview.getSettings().setAppCacheMaxSize(1024*1024*8);
    _webview.getSettings().setAppCachePath("/data/data/com.your.package.appname/cache");
    _webview.getSettings().setAllowFileAccess(true);
    _webview.getSettings().setAppCacheEnabled(true);

MyWebClient:

private class MyWebViewClient extends WebViewClient {

    @Override
    public void onLoadResource(WebView view, String url) {
        Log.d("MyWebViewClient",url);
    }
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        showProgressDiag();
        Log.d("MyWebViewClient","shouldOverride... : " + url);
        view.loadUrl(url);
        return true;
    }
    @Override
    public void onPageFinished(WebView view, String url){
        hideProgressDiag();
    }
    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {

        if(failingUrl.equals("file:///android_asset/html/error.html")){
            hideProgressDiag();
            Toast.makeText(_context, "Error! Check internet connection, or try again later...", Toast.LENGTH_SHORT).show();
        }
        else {
            Toast.makeText(_context, failingUrl, Toast.LENGTH_SHORT).show();

            view.loadUrl("file:///android_asset/html/error.html");
        }

    }

}

MyChromeClient:

private class MyChromeClient extends WebChromeClient{

    @Override
    public void onProgressChanged(WebView view, int progress) {
     Pdiag.setProgress(progress * 100);
    }

}

当单击指向 javascript 函数的链接之一时,所发生的一切是 WebView 变为灰色,而没有通过 shouldOverrideUrlLoading()。当我按下返回键时,应用程序退出,这意味着 WebView 的导航历史记录中没有任何内容。有时什么也没有发生,但随后 shouldOverrideUrlLoading() do run 并且从 Log.d() 我可以看到弹出窗口的正确 URL 已提供给 WebView。

问题是,在极少数情况下它显示得很好,但我不知道如何重现它,它是否真的显示在弹出窗口中。

我迷路了...而且很沮丧...想看一部糟糕的情景喜剧 :(

编辑: 实际上,也许 URL 并不完全正确......在 Firefox 中,URL 以“X

编辑 2: 不,没有做任何事情...该 URL 与 Firefox 中的相同...

【问题讨论】:

  • 看起来那些类型的 javascript url 更改不能可靠地调用 shouldOverrideUrlLoading。也许有解决您的问题的解决方法或骇人听闻的方法。假设它能够被正常捕获,一旦捕获它你想做什么?
  • 目前我什么都不做。昨天开的还不错。它看起来不像一个浮动弹出窗口,但至少它出现了。但是由于脚本生成了正确的 url,理想情况下我会抓住那个 url 并用它做一个 loadUrl() 。但如果这有效,我如何阻止它加载两次,由我手动和由 webview 自动加载?我在哪里截取网址?在 LoadResource() 上?
  • 如果你不覆盖 shouldOverrideUrlLoading() 或者只在其中返回 false,它会正确加载吗?问题是什么?是不是因为这样加载时它不在后退按钮历史记录中?
  • 我会检查如果我不覆盖 shouldOver...() 会发生什么。问题是 80% 的时间我点击链接,唯一发生的事情是 webview 变成灰色(可能是我的 bgcolor,我会尝试将其更改为更时髦的颜色来验证),10% 的时间没有任何反应, 尽管 onLoadRes...() 被正确的 url 调用,并且剩余 10% 的点击给出了正确的结果,尽管不像标准浏览器显示的那样在浮动弹出窗口中。
  • 我将能够在凌晨尝试您的建议。我只是不明白为什么 webview 的行为应该与浏览器不同。它在浏览器中完美运行,所以当我不想更改内容或显示方式时,为什么我必须破解 html。我一直觉得这只是一些愚蠢的事情,比如 setJavascriptCanOpenWindows() 放在错误的行之类的......

标签: javascript android popup android-webview


【解决方案1】:

首先,您需要在WebView 上进行以下设置:

WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setSupportMultipleWindows(true);

然后您需要附加一个覆盖onCreateWindowWebChromeClient。您对该方法的实现可以创建一个新的 Web 视图,并将其显示在对话框中:

webView.setWebChromeClient(new WebChromeClient() {

        @Override
        public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
            WebView newWebView = new WebView(MyActivity.this);
            WebSettings webSettings = newWebView.getSettings();
            webSettings.setJavaScriptEnabled(true);

            // Other configuration comes here, such as setting the WebViewClient

            final Dialog dialog = new Dialog(MyActivity.this);
            dialog.setContentView(newWebView);
            dialog.show();

            newWebView.setWebChromeClient(new WebChromeClient() {
                @Override
                public void onCloseWindow(WebView window) {
                    dialog.dismiss();
                }
            });

            ((WebView.WebViewTransport)resultMsg.obj).setWebView(newWebView);
            resultMsg.sendToTarget();
            return true;
        }

});

不要忘记将新的 Web 视图设置为 resultMsg,将其发送到其目标并返回 true,如 the API documentation 中所述。

【讨论】:

  • 我想添加以下代码: ... final Dialog dialog = new Dialog(MyActivity.this);对话框.setContentView(newWebView);对话框.show();窗口窗口 = dialog.getWindow(); window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); newWebView.setWebViewClient(new WebViewClient()); .... 这会生成一个全屏对话框,并在您的 webview 中打开。
  • 向你致敬,兄弟,拯救了我的一天。创建窗口的处理非常优雅,可以与付款方式和自动关闭一起使用。谢谢你兄弟
【解决方案2】:

请检查添加这个 -

    getSettings().setSupportMultipleWindows(true);

【讨论】:

  • 天哪,谢谢!我会检查的。不知道我什么时候才能找到时间。这不是我现在最活跃的项目......当我尝试它时,如果它有效,我会标记你的解决方案!我保证!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-16
  • 2012-09-19
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多