是否可以在不使用Javascript的情况下检索Web引擎中的HTML元素?

Nav*_*waj 3 html dom javafx webview javafx-webengine

有没有办法使用?识别被点击的元素的类型webView(如文本框/广播/按钮等)webEngine.getDocument()

假设我点击文本字段,我可以得到点击位置的x,y坐标.是否有可能识别该特定位置的元素?像document.elementFromPoint()Javascript中的方法.

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

jew*_*sea 8

您可以对从WebEngine检索到的文档使用Java语言绑定for Dom Level 2事件.这些绑定是为了访问与人们在浏览器中编写网页事件时使用的JavaScript事件绑定相同的功能.

引用的类随JDK一起提供.

在访问文档之前,只需确保文档已完全加载(通过监视工作者状态文档属性).

注意:您在问题中引用的特定方法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);
    }
}
Run Code Online (Sandbox Code Playgroud)

你可能会注意到,即使你想要的elementFromPoint方法是可用的......虽然这里并不严格需要,因为你可以从专家鼠标中获取事件目标目录.

该示例仅将检索到的元素视为标准的w3c dom元素,它具有(对我来说)特别神秘的API.但是,您可以将元素转换为适当的com.sun.webkit.dom.HTMLElementImpl子类,以获得更容易访问的功能和更好,更直接的API,以反映使用JavaScript时使用HTML DOM时可能习惯的内容.