2022 年更新
从 JDK 8 开始,当这个答案被写出来时,JDK 已经模块化了。要访问此处引用的一些 API,您需要在您的应用程序中需要适当的模块module-info.java
如果您有模块化应用程序。
涉及的各个模块:
-
javafx.web
用于 JDK Web 引擎。
-
jdk.xml.dom
为了org.w3c.com.html
包裹。
-
java.xml
为了org.w3c.dom
包裹。
相关包及其关联模块的更详细记录位于:
-
org.w3c.dom包文档 https://docs.oracle.com/en/java/javase/17/docs/api/java.xml/org/w3c/dom/package-summary.html.
其中引用了 Java API 的相关包来处理 HTML、XML、CSS、事件、文档遍历、XPath 处理等。
请注意,通过从 WebEngine 加载的网页中嵌入的 javascript 查询 DOM,也可以使用相同的功能。对于大多数开发人员来说,JavaScript API 比此处引用的 Java API 使用起来更方便、更实用。 JavaScript API 也可以通过支持 JavaScript 库(例如 jquery)来间接使用,这大大简化了DOM https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction.
原答案
你也许可以使用Dom 2 级事件的 Java 语言绑定 http://www.w3.org/TR/DOM-Level-2-Events/java-binding.html在从 WebEngine 检索到的文档上。这些是访问与JavaScript 事件绑定 http://www.w3.org/TR/DOM-Level-2-Events/ecma-script-binding.html人们在浏览器中为网页编写事件时使用。
引用的类是随 JDK 一起提供 https://docs.oracle.com/javase/8/docs/api/org/w3c/dom/events/package-summary.html.
只需确保文档已完全加载(通过监视工人国家 https://docs.oracle.com/javase/8/javafx/api/javafx/scene/web/WebEngine.html or the 文件属性 https://docs.oracle.com/javase/8/javafx/api/javafx/scene/web/WebEngine.html#documentProperty)在访问它之前。
Note:您在问题中引用的特定方法document.elementFromPoint() http://www.w3.org/TR/cssom-view/#dom-document-elementfrompoint,不是 DOM level 2 规范的一部分,而是定义为 CSSOM 视图模块中文档接口的扩展,它“为作者提供了一种检查和操作文档可视视图的方法”。虽然 DOM 级别 2 规范是通过 org.w3c 模块在 JDK 中实现的,但 CSSOM 视图模块扩展却不是。
好的,所以下一部分有点不合时宜,因为它没有记录在官方标准 JDK Javadoc 中。因此,需要注意一些警告,例如“可能不适用于所有 JavaFX 实现”或“可能并不总是受到 Oracle 的支持”或“可能会在未来的 Java 版本中中断”。但无论如何,继续有趣的事情......
WebView中的document属性实际上是一个实现org.w3c.dom.html.HTMLDocument https://docs.oracle.com/javase/8/docs/jre/api/plugin/dom/org/w3c/dom/html/HTMLDocument.html接口记录在这个奇怪的位置:https://docs.oracle.com/javase/8/docs/jre/api/plugin https://docs.oracle.com/javase/8/docs/jre/api/plugin。该接口和所有支持的 Java HTML 文档建模类随 JavaFX 一起随 Oracle Java Runtime 8 一起提供。 HTMLDocument 接口和关联的类形成了比标准 JDK 文档中记录的普通 org.w3c.Document 接口更丰富的 API。
因此,您可以将文档转换为 HTMLDocument,并且您将获得更多功能。
然而,即便如此,浏览器(和 WebView 文档)中仍有许多功能不是由纯 HTMLDocument 界面公开的。
因此,您可以通过将文档转换为com.sun.webkit.dom.HTMLDocumentImpl
。然后,您将暴露出名副其实的 API 狂欢。
那么让我们这样做...这里我捕获了 HTML div 元素上的鼠标事件。
这是一个(非常)简单的 Web 检查器,就像 Firebug 一样。将鼠标悬停在 JavaFX WebView 中的元素上,该元素的一些最小信息将显示在屏幕顶部的 JavaFX 标签中。
import com.sun.webkit.dom.HTMLDocumentImpl;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import org.w3c.dom.events.MouseEvent;
public class WebViewClicker extends Application {
public static final String LOC =
"http://stackoverflow.com/questions/31957218/is-it-possible-to-retrieve-html-element-in-web-engine-without-using-javascript";
@Override
public void start(Stage stage) throws Exception {
Label elementInfo = new Label();
WebView webview = new WebView();
webview.getEngine().documentProperty().addListener((observable, oldDoc, newDoc) -> {
HTMLDocumentImpl realMcCoy = (HTMLDocumentImpl) newDoc;
realMcCoy.setOnmousemove(event -> {
MouseEvent expertMouser = (MouseEvent) event;
elementInfo.setText(
realMcCoy.elementFromPoint(
expertMouser.getClientX(),
expertMouser.getClientY()
).toString()
);
});
});
webview.getEngine().load(LOC);
stage.setScene(new Scene(
new VBox(
elementInfo,
webview
)
));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
您可能会注意到,即使是您想要的elementFromPoint
方法可用...尽管这里并不严格需要它,因为您可以从专家鼠标器获取事件目标目录。
该示例只是将检索到的元素视为标准 w3c dom 元素,它(对我来说)有一个特别神秘的 API。但是您可以将元素转换为适当的com.sun.webkit.dom.HTMLElementImpl 子类 http://hg.openjdk.java.net/openjfx/9-dev/rt/file/tip/modules/web/src/main/java-wrappers/com/sun/webkit/dom获得更容易访问的功能和更好、更直接的 API,它反映了您在使用 JavaScript 处理 HTML DOM 时可能习惯的东西。