的WebView跳转到锚使用loadDataWithBaseUrl(WebView jump to

2019-07-17 15:23发布

我的Android应用程序使用的WebView显示了一堆,我“对飞”生成的HTML代码。 的HTML代码用下面的代码加载:

    StringBuilder builder = new StringBuilder();

    // HTML
    builder.append("<html><head><link rel=\"stylesheet\" href=\"file:///android_asset/style.css\" type=\"text/css\">");
    builder.append("</link></head><body>");
    builder.append(getThreadBody());
    builder.append("</body></html>");

    webview.loadDataWithBaseURL("file:///android_asset/", builder.toString(), "text/html", "utf-8", null);

这一切工作真的很好。 请注意,我不加载实际的HTML文件,我只是创建代表一些(希望有效)HTML和web视图加载一个字符串。

无论如何,HTML我生成(在“getThreadBody”方法的部分)包含名为锚,例如像这样的;

<div>
    <a name="949823">Anchor 1</a>
    <div>All kinds of stuff</div>

    <a name="895984">Anchor 2</a>
    <div>...</div>
</div>

现在,在某些情况下,我想的WebView尽快我加载HTML浏览到这些锚之一。 据我了解的WebView支持导航(在这种情况下滚动)来命名锚,但美中不足的是,没有人点击任何链接到这些锚,我希望它被装载时的WebView滚动(它是,如果没有问题的存在为加载HTML和滚动之间的一个短暂的延迟,我的观点是,它不应该要求用户交互)。

我相信行为可以使用的WebView使用loadURL方法,并在适当位置锚提供一个URL,例如可以实现

webview.loadUrl("file:///android_asset/page.html#895984", ...)

然而,由于我没有保存的HTML的任何文件,我不能用这种方法...当然的HTML保存到临时文件可能是一个解决方案,但我想继续,作为最后的手段,必须有一个更简单的方法?

我怎样才能做到这一点? 谢谢!


解决下面是工作的代码。 我发现了一个很短的延迟被要求让页面加载执行JavaScript之前,否则它是一种50/50无论是工作或不...

    StringBuilder builder = new StringBuilder();

    // HTML
    builder.append("<html><head><link rel=\"stylesheet\" href=\"file:///android_asset/style.css\" type=\"text/css\">");
    builder.append("</link>");
    builder.append("<script>");
    builder.append("function scrollAnchor(id) {");
    builder.append("window.location.hash = id;}");
    builder.append("</script>");
    builder.append("</head><body>");
    builder.append(getThreadBody());
    builder.append("</body></html>");

    webContents.loadDataWithBaseURL("file:///android_asset/", builder.toString(), "text/html", "utf-8", null);

    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            String id = "895884";
            webContents.loadUrl("javascript:scrollAnchor(" + id + ");");
        }
        }
    }, 250);

Answer 1:

如何控制它由JavaScript? 我没有尝试,但也许这是一个线索。

builder.append(getThreadBody());
builder.append("<script>window.location.hash="949823";</script>");
builder.append("</body></html>");

记住启用的WebView的JavaScript。

----附加应答----

我看到你使用的TimerTask加载的JavaScript,工作原理,但我认为还有另一种更好的办法。 的WebView有一个回调命名onPageFinished,这将是触发时的WebView完成加载网页。 你可以有你的注入JS。

webContents.setWebViewClient(new WebViewClient(){

    @Override
    public void onPageFinished(WebView view, String url) {
          String id = "895884";
          webContents.loadUrl("javascript:scrollAnchor(" + id + ");");
    }

});

希望这是有用的!



Answer 2:

首先,你不需要使用JavaScript。 如果加载的内容与

webContents.loadDataWithBaseURL("some://dummy/url",...);

你可以简单地滚动与锚

webContents.loadUrl("some://dummy/url#anchor");

其次,这样做对onPageFinished无需额外的控制效果在永无止境的循环! 当使用loadURL完成onPageFinished得到的一再呼吁。



Answer 3:

如果有外部动作(如: onclick event ),试试这个代码

 public static void scrollToAnchor(String id) {
        sWebView.loadUrl("javascript:document.getElementById(\"" + id + "\").scrollIntoView()");
 }


Answer 4:

如果您加载从html的assets

 webView.loadUrl("file:///android_asset/htmls/mypage.html#anchor");

你可以移动到网页中的锚:

webView.loadUrl("http://www.stackoverflow.com/mypage.html#anchor");


文章来源: WebView jump to anchor using loadDataWithBaseUrl