注意:这是关于JavaFX WebView,而不是Android WebView(即我已经看过" Android Webview Anchor Link (Jump link) not working")。
我在javafx.scene.web.WebView
中显示一个生成的HTML页面,其中包含锚点和指向这些锚点的链接:
<p>Jump to <a href="#introduction">Introduction</a></p>
some text ...
<h1 id="introduction">Introduction</h1>
more text ...
我使用此代码将HTML加载到WebView中:
public void go(String location) {
try {
// read the content into a String ...
String html = NetUtil.readContent(new URL(location), StandardCharsets.UTF_8);
// ... and use loadContent()
webview.getEngine().loadContent(html);
} catch (IOException e) {
LOG.error(e);
}
}
所有内容都正确呈现,但如果我点击名为&#34;简介&#34;的链接,则没有任何反应。
然而HTML是正确的,我使用此代码检查了它:
public void go(String location) {
// use load() to directly load the URL
webview.getEngine().load(location);
}
现在,一切都很好。
问题似乎在某种程度上是因为使用null
时WebView的文档URL为loadContent()
,但由于它只是一个readonly属性,所以我不知道如何让它工作。
我需要使用loadContent()
,因为HTML是动态生成的,如果可能的话,我不想将其写入文件只是为了制作锚链接工作。有办法解决这个问题吗?
修改 我为JavaFX提交了bug。
答案 0 :(得分:2)
可能是另一个WebEngine 错误。很多代码只是包含在api中的本机库,因此我们无法在运行时修改它来修复一些残障。
如果您能够更改生成文件的结构,则可以在js中实现滚动到元素:
<script>
function scrollTo(elementId) {
document.getElementById(elementId).scrollIntoView();
}
</script>
<a href='#' onclick=scrollTo('CX')>Jump to Chapter X</a>
<h2 id="CX">Chapter X</h2>
如果您无法更改结构,我会尝试修改一些步骤并提出一些建议 - 首先我设置了location
的值loadContent
之后的反思肯定:
Field locationField = WebEngine.class.getDeclaredField("location");
locationField.setAccessible(true);
ReadOnlyStringWrapper location = (ReadOnlyStringWrapper) locationField.get(engine);
location.set("local");
但事实上,保持实际位置的状态只是一个信息给你,操纵这个改变什么都没有。我也找到了一种从js设置网址的方法(只是一个很长的镜头,我们没有具体的细节,为什么它不工作):
window.history.pushState("generated", "generated", '/generated');
当然,我们不能因为:
SecurityError: DOM Exception 18: An attempt was made to break through the security policy of the user agent.
我认为你应该忘记loadContent()
。你说你不想把生成的内容写入文件。一点脏黑客但对你真的很有帮助,可以在应用程序中的随机和未使用的端口上包装http服务器。您甚至不需要外部库,因为Java具有类似的简单实用程序:
HttpServer server = HttpServer.create(new InetSocketAddress(25000), 0);
server.createContext("/generated", httpExchange -> {
String content = getContent();
httpExchange.sendResponseHeaders(200, content.length());
OutputStream os = httpExchange.getResponseBody();
os.write(content.getBytes());
os.close();
});
server.setExecutor(null);
server.start();
您还可以使用其他浏览器来显示您的网页,例如JCEF( Java Chromium Embedded Framework )。