WebView使用loadDataWithBaseUrl跳转到锚点

2023-11-21

我的 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 的字符串并将其加载到 WebView 中。

无论如何,我生成的 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 保存到临时文件可能是一个解决方案,但我想将其作为最后的手段,必须有一个更简单的方法?

我怎样才能实现这个目标?谢谢!


Resolved这是有效的代码。我发现在执行 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);

用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 + ");");
    }

});

希望这有用!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebView使用loadDataWithBaseUrl跳转到锚点 的相关文章

随机推荐