【问题标题】:Is it possible to retrieve HTML element in web engine without using Javascript?是否可以在不使用 Javascript 的情况下在 Web 引擎中检索 HTML 元素?
【发布时间】:2015-08-12 06:08:40
【问题描述】:

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

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

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

【问题讨论】:

标签: html dom webview javafx javafx-webengine


【解决方案1】:

您可能可以在从 WebEngine 检索到的文档上使用Java Language Binding for Dom Level 2 events。这些绑定用于访问与人们在浏览器中为网页编程事件时使用的 JavaScript event bindings 相同的功能。

引用的类是shipped with the JDK

在访问之前确保文档已完全加载(通过监视worker statedocument property)。

注意:您在问题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 subclass 以获得更易于访问的功能和更好、更直接的 API,以反映您在使用 JavaScript 处理 HTML DOM 时可能习惯的一些东西。

【讨论】:

  • 如果我这样做了,event.getTarget() 每次点击都会返回我的 WebView。所以,我无法映射特定元素。
  • 当我运行你的程序时,我收到一个错误,比如我如何修复错误:无法访问 XPathEvaluator realMcCoy.setOnmousemove(event -> { org.w3c.dom.xpath.XPathEvaluator 的类文件未找到
  • @MaTâm 我尝试运行该程序,它运行良好,没有错误(OS X 10.9.5 上的 jdk1.8.0_72)。我不知道你为什么它不适合你马。
  • 我在 Windows 7 下使用最新的 NetBean 和 jdk1.8.0_91 出现以下错误 => cannot access XPathEvaluator realMcCoy.setOnmousemove(event -> { class file for org.w3c.dom.xpath .XPathEvaluator 未找到
猜你喜欢
  • 1970-01-01
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
  • 2021-09-16
  • 2014-04-02
  • 1970-01-01
  • 2018-05-21
  • 1970-01-01
相关资源
最近更新 更多