无法在移动设备上禁用 JavaFX WebView 超链接
JavaFX WebView HyperLinks Cannot Be Disabled on Mobile Devices
以下代码用于禁用 JavaFX WebView 对象中的超链接。但是,当我 运行 它在移动设备上无法运行时,在桌面上运行正常。有影响移动设备的替代解决方案吗?
private void init() {
webEngine = webView.getEngine();
webEngine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
if(newState == State.SUCCEEDED && webEngine.getDocument() != null)
disableHyperLinks(webEngine.getDocument());
});
} // init()
private void disableHyperLinks(Document document) {
NodeList nodeList = document.getElementsByTagName("a");
for (int i = 0; i < nodeList.getLength(); i++)
{
Node node= nodeList.item(i);
EventTarget eventTarget = (EventTarget) node;
eventTarget.addEventListener("click", (evt) -> {
evt.preventDefault();
}, false);
} // for
} // disableHyperLinks()
当您 运行 在移动设备上时,WebView 不是使用 JavaFX 控件实现的,而是使用本机控件,Android 和 iOS。
您可以看到 here the implementation for Android, and here iOS 的那个。
在iOS上没有实现Document
本地方法,它只returns加载页面的html内容(前提是内容可以解析,否则将为空)。所以即使你能够读取和修改那些内容,对真正的控制也没有任何影响。
好消息是您可以使用 executeScript
,因为 implemented 用于 iOS。
像这样的东西应该可以工作:
private void init() {
webEngine = webView.getEngine();
webEngine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
if(newState == State.SUCCEEDED)
disableHyperLinks();
});
} // init()
private void disableHyperLinks() {
Object res = webView.getEngine().executeScript("(function() { " +
"var links = document.getElementsByTagName(\"a\");\n" +
" for (var i=0; i<links.length; i++) {\n" +
" links[i].addEventListener(\"click\",function(e) {\n" +
" e.preventDefault();\n" +
" })\n" +
" }"
+ "return ('<html>'+ links.length +'</html>'); })();");
if (res != null) {
System.out.println("Hyperlinks disabled: " + res);
} else {
System.out.println("ERROR disabling hyperlinks");
}
} // disableHyperLinks()
不过,以上代码不适用于 Android。有一种(非常 hacky)可能的方法可以做到这一点,在 运行 时间访问本机控件(但由于问题是关于 iOS 我不会在这里解释)。
以下代码用于禁用 JavaFX WebView 对象中的超链接。但是,当我 运行 它在移动设备上无法运行时,在桌面上运行正常。有影响移动设备的替代解决方案吗?
private void init() {
webEngine = webView.getEngine();
webEngine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
if(newState == State.SUCCEEDED && webEngine.getDocument() != null)
disableHyperLinks(webEngine.getDocument());
});
} // init()
private void disableHyperLinks(Document document) {
NodeList nodeList = document.getElementsByTagName("a");
for (int i = 0; i < nodeList.getLength(); i++)
{
Node node= nodeList.item(i);
EventTarget eventTarget = (EventTarget) node;
eventTarget.addEventListener("click", (evt) -> {
evt.preventDefault();
}, false);
} // for
} // disableHyperLinks()
当您 运行 在移动设备上时,WebView 不是使用 JavaFX 控件实现的,而是使用本机控件,Android 和 iOS。
您可以看到 here the implementation for Android, and here iOS 的那个。
在iOS上没有实现Document
本地方法,它只returns加载页面的html内容(前提是内容可以解析,否则将为空)。所以即使你能够读取和修改那些内容,对真正的控制也没有任何影响。
好消息是您可以使用 executeScript
,因为 implemented 用于 iOS。
像这样的东西应该可以工作:
private void init() {
webEngine = webView.getEngine();
webEngine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
if(newState == State.SUCCEEDED)
disableHyperLinks();
});
} // init()
private void disableHyperLinks() {
Object res = webView.getEngine().executeScript("(function() { " +
"var links = document.getElementsByTagName(\"a\");\n" +
" for (var i=0; i<links.length; i++) {\n" +
" links[i].addEventListener(\"click\",function(e) {\n" +
" e.preventDefault();\n" +
" })\n" +
" }"
+ "return ('<html>'+ links.length +'</html>'); })();");
if (res != null) {
System.out.println("Hyperlinks disabled: " + res);
} else {
System.out.println("ERROR disabling hyperlinks");
}
} // disableHyperLinks()
不过,以上代码不适用于 Android。有一种(非常 hacky)可能的方法可以做到这一点,在 运行 时间访问本机控件(但由于问题是关于 iOS 我不会在这里解释)。