有没有办法使用webView
识别webEngine.getDocument()
中的点击元素的类型(如文本框/广播/按钮等)?
假设我点击了一个文本字段,我可以得到点击位置的x,y坐标。是否有可能识别该特定位置的元素?类似于Javascript中的document.elementFromPoint()
方法。
我可以使用Jquery / Javascript来做到这一点。但由于我们可以访问Document
对象及其元素,有没有办法识别使用JavaFX本身?
答案 0 :(得分:8)
您可以在从WebEngine检索到的文档上使用Java Language Binding for Dom Level 2 events。这些绑定是为了访问与人们在浏览器中编写网页事件时使用的JavaScript event bindings相同的功能。
引用的类是shipped with the JDK。
在访问文档之前,请确保文档已完全加载(通过监控worker state或document property)。
注意:您在问题document.elementFromPoint()
中引用的特定方法不是DOM级别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。此接口和所有支持的Java HTML文档建模类随Oracle Java Runtime 8以及JavaFX一起提供。与标准JDK文档中记录的普通org.w3c.Document接口相比,HTMLDocument接口和相关类构成了更丰富的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 subclass以获得更易于访问的功能,以及更好,更直接的API,它反映了您在使用JavaScript处理HTML DOM时可能习惯的内容。