3

有没有办法webView使用webEngine.getDocument()

假设我点击一个文本字段,我可以获得点击位置的 x,y 坐标。是否可以识别该特定位置中存在的元素?类似于document.elementFromPoint()Javascript 中的方法。

我可以使用 Jquery/Javascript 来做到这一点。但是既然我们可以访问Document对象及其元素,有没有办法使用 JavaFX 本身来识别呢?

4

1 回答 1

8

您可能可以对从 WebEngine 检索到的文档使用Java 语言绑定来处理 Dom 级别 2 事件。这些绑定用于访问与人们在浏览器中为网页编程事件时使用的JavaScript 事件绑定相同的功能。

引用的类随 JDK 一起提供

只需确保文档已完全加载(通过监视工作人员状态文档属性),然后再访问它。

注意:您在问题document.elementFromPoint()中引用的特定方法不是 DOM 2 级规范的一部分,而是定义为 CSSOM 视图模块中文档接口的扩展,它“为作者提供了一种检查和操作视觉查看文档”。虽然 DOM 级别 2 规范是在 JDK 中使用 org.w3c 模块实现的,但 CSSOM 视图模块扩展却没有。


好的,所以下一部分有点保留,因为它没有记录在官方标准 JDK Javadoc 中。因此,诸如“可能不适用于所有 JavaFX 实现”或“可能并不总是受 Oracle 支持”或“可能会在未来的 Java 版本中中断”之类的警告适用。但无论如何,关于有趣的事情......

WebView 中的文档属性实际上是org.w3c.dom.html.HTMLDocument接口的实现,该接口记录在这个奇怪的位置:https ://docs.oracle.com/javase/8/docs/jre/api/plugin . 该接口和所有支持的 Java HTML 文档建模类随 Oracle Java Runtime 8 和 JavaFX 一起提供。HTMLDocument 接口和相关类形成了比标准 JDK 文档中记录的普通 org.w3c.Document 接口更丰富的 API。

因此,您可以将文档转换为 HTMLDocument,您将获得更多功能。

然而,即便如此,浏览器(和 WebView 文档)中仍有许多功能不是由纯 HTMLDocument 接口公开的。

因此,您可以通过将文档转换为com.sun.webkit.dom.HTMLDocumentImpl. 然后你公开了一个名副其实的 API 狂欢。

所以让我们这样做...这里我在 HTML div 元素上捕获鼠标事件。

样品检验

这是一个(非常)简单的网络检查器,比如 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 子类,以获得更容易访问的功能和更好、更直接的 API,它反映了您在使用 JavaScript 处理 HTML DOM 时可能习惯的东西.

于 2015-08-12T08:45:25.240 回答