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

2024-01-08

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

假设我单击一个文本字段,我可以获得单击位置的 x,y 坐标。是否可以识别该特定位置中存在的元素?像这样的东西document.elementFromPoint()JavaScript 中的方法。

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


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 时可能习惯的东西。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • gradle - 无法从 Maven 存储库中找到依赖项

    我在使用以下 build gradle 时遇到构建错误 apply plugin java apply plugin idea sourceCompatibility 1 7 version 1 0 repositories mavenLo
  • Magento - 数据未插入数据库,但id自动递增

    我正在为 Magento 开发一个新的支付模块 并且遇到了一个我无法解释的问题 验证信用卡后运行以下代码 table prefix Mage getConfig gt getTablePrefix tableName table prefi
  • cURL 错误 1:不支持的协议:https

    All 我尝试通过 PHP 的 cURL 包装器方法 HTTPS POST SOAP 请求 但不断收到以下 cURL 错误 错误 1 不支持的协议 https 有什么想法为什么会发生这种情况吗 目标 URL 很好 我可以通过命令行访问它 c
  • 如何从另一个 ViewController 修改 UITableView 的单元格

    在 VC 1 中 我有一个 UITableView 当我点击一个单元格时 我会进入 VC 2 其中显示有关该单元格的信息 我希望能够在 VC 2 中按下一个按钮 从而更改它在 VC 1 中对应的单元格的标题 但我对如何执行此操作感到困惑 我
  • 将请求参数作为 UTF-8 编码字符串传递[重复]

    这个问题在这里已经有答案了 我正在创建一个简单的登录页面 我想将登录名和密码参数作为 UTF 8 编码字符串传递 正如您在下面的代码中看到的 第一行是我将编码设置为 UTF 8 的地方 但这似乎毫无意义 因为它不起作用 当我使用带有重音符号
  • 交换活动后如何保持倒计时计时器计数?

    当我在活动之间交换时 我需要一个 countDownTimer 继续运行 我有多个活动 我将 countDownTimer 放在主活动中 但是当我交换到另一个活动并返回到主活动时 它又会从头开始重新计数 我相信是因为 countDownTi
  • 使用 pysftp 或 Paramiko,如何获得包含属性的完整目录列表?

    正如标题所示 我正在尝试获取目录中所有文件和目录的列表 包括它们的属性 我正在寻找至少名称 大小 上次修改时间 以及它是文件还是文件夹 我在 Windows 上使用 Python 3 我试过了listdir 我得到了一个没有属性的文件列表
  • java.lang.Long 和 scala.Long

    我不知道我的代码中发生了什么 日志在这里 error blahblah SampleApp scala 22 53 overloaded method value reduce with alternatives error func or
  • Oracle“总”计划成本确实低于其某些要素

    我不明白为什么有时一个计划的总成本可能很小 但查看计划内部我们会发现巨大的成本 确实查询速度很慢 有人能给我解释一下吗 这是一个例子 显然 成本较高的部分来自主选择中的一个字段 该字段在子视图上执行 listagg 并且该子视图的连接条件包
  • 在运行时创建XmlRpcUrl接口

    目前 我正在使用 xml rpc net 接口通过以下语句静态创建 XML RPC XmlRpcUrl http dillieodigital wordpress com xmlrpc php public interface ICSBlo
  • DLLImport 在哪里查找非托管 DLL?

    一个简单的问题 在 Net 中声明 DLLImport 属性时 运行时在哪里寻找解决该 DLL 依赖关系的方法 我是否必须转储 DLL 和所有itsbin 文件夹中的依赖项 我认为它的工作方式与 LoadLibrary 类似 Maybe 使
  • 如何比较 PHAsset 和 UIImage

    我已经转换了一些PHAsset to UIImage PHImageManager manager PHImageManager defaultManager manager requestImageForAsset asset targe
  • 隐藏页面中的div并使其仅在打印引导程序3 MVC 5上可见

    有一个网页向用户显示信息 如果用户决定打印它 我想包含屏幕上不需要的附加信息 但在打印时会很有帮助 为了实现这种行为 我试图做一个div仅在打印时可见 但它并没有起作用 div class visible print hidden lg h
  • 如何构建卡方分布表

    我想在 python 中生成一个卡方分布表作为概率水平和自由度的函数 给定已知的卡值和自由度 如何计算概率是这样的 In 44 scipy stats chisqprob 5 991 2 Out 44 0 05001161502657908
  • 在 git rebase -i 中删除提交不会减少 .git 文件夹的大小

    我有一个 git 存储库 其中 git文件夹是7MB 然后我添加并提交了一个 exe 文件 该文件是16MB其次是 git gc aggressive git prune 经过上述我的 git文件夹现在是23MB 接下来我做了一个git r
  • sklearn Kfold 访问单折叠而不是 for 循环

    使用 cross validation KFold n n folds folds 之后 我想访问索引以进行单折叠的训练和测试 而不是遍历所有折叠 那么我们来看一下示例代码 from sklearn import cross validat
  • 有没有一种方法可以在不使用暂存缓冲区的情况下更新纹理?

    我正在与https vulkan tutorial com https vulkan tutorial com 深度缓冲代码作为基础 进行了一些更改以每帧更新命令缓冲区 我正在使用一种粗略的方法来检查 fps 不确定它到底有多准确 但我正在
  • 亲子信号沟通陷入僵局

    我已经实现了两个程序 parent cpp child c 它们应该通过信号进行通信 以交替方式无限期地工作 然而 由于某种原因 程序在随机的时间后进入死锁 我无法弄清楚为什么 发送给父进程的信号似乎在没有执行信号处理程序的情况下被丢弃 因
  • git log --follow 已重命名的目录有什么技巧吗?

    git 命令有一个有用的命令可以在重命名后跟踪文件 如下所示git log follow path to some file 不幸的是 它仅适用于单个文件 我希望能够做相当于git log follow some directory 做到这
  • 是否可以在不使用 Javascript 的情况下在 Web 引擎中检索 HTML 元素?

    有没有办法识别点击元素的类型webView 如文本框 单选按钮 按钮等 使用webEngine getDocument 假设我单击一个文本字段 我可以获得单击位置的 x y 坐标 是否可以识别该特定位置中存在的元素 像这样的东西docume