【问题标题】:Is it possible to detemine element location in WebView in JavaFX?是否可以在 JavaFX 中确定 WebView 中的元素位置?
【发布时间】:2014-01-03 16:56:12
【问题描述】:

假设我已将一些 HTML 加载到 WebView。假设这个 HTML 包含一些 DIV 元素。我可以在渲染后确定这个 DIV 元素的几何位置吗?这样我就可以跟踪鼠标点是否在它上面。

更新

是的,问题是关于不是我的外部网页。我想用 Java 对页面进行一些彻底的探索。

我读到WebView 是用WebKit 实现的。那么是否可以从 Java 访问任何 WebKit 内部?

还有。除了已经加载的页面并调用offset()函数之外,是否可以下载jquery?

【问题讨论】:

  • This discussion 有一些解决方案可以在 webview 中的任意页面上执行 jquery。

标签: java dom webview webkit javafx


【解决方案1】:

没有办法(据我所知)获取 div 的屏幕坐标。

但是,您可以从 Javascript 回调您的 Java 代码。因此,您可以编写少量 Javascript 来检测鼠标何时进入和退出 div,并调用一些更新 BooleanProperty 的 Java 代码,例如。请参阅WebEngine API docs 中的“从 Javascript 回调 Java”。

更新:示例

更新:简化代码

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import netscape.javascript.JSObject;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker.State;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class HTMLMouseOverTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        final BorderPane root = new BorderPane();
        final WebView webView = new WebView();
        final WebEngine engine = webView.getEngine();
        final BooleanProperty mouseOver = new SimpleBooleanProperty();
        engine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {

            @Override
            public void changed(ObservableValue<? extends State> observable,
                    State oldValue, State newValue) {
                if (newValue == State.SUCCEEDED) {
                    // Here's how to add the Javascript if you don't have
                    // direct access to the HTML:
//                    final Document doc = engine.getDocument();
//                    Element div = doc.getElementById("important-div");
//                    div.setAttribute("onmouseover", "mouseOverProperty.set(true)");
//                    div.setAttribute("onmouseout", "mouseOverProperty.set(false)");
                    final JSObject window = (JSObject) engine.executeScript("window");
                    window.setMember("mouseOverProperty", mouseOver);                    
                }
            }
        });
        engine.loadContent("<html><body style='font-family:sans-serif';><h2>Hello World</h2>"+
            "<div id='important-div' onmouseover='mouseOverProperty.set(true)'"+
                "onmouseout='mouseOverProperty.set(false)' style='background: #ffd; padding:40px;'>"+ 
            "Move mouse here</div>"+
            "<h3>Thanks and good night</h3></body></html>");

        root.setCenter(webView);
        final Label label = new Label();
        label.textProperty().bind(Bindings.when(mouseOver).then("Mouse in position").otherwise("Mouse out of area"));
        root.setBottom(label);
        final Scene scene = new Scene(root, 400, 250);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

【讨论】:

  • 如果您无法控制正在加载的 HTML(例如,它来自外部站点),您可以操作 DOM 并在加载页面时插入所需的 Javascript。这开始有点混乱,但它会起作用。 WebEngine 的相同文档展示了如何访问 DOM。
【解决方案2】:

渲染发生在客户端。在服务器上获取这些信息的唯一方法是编写 JS 代码来收集这些数据,然后将它们发送到服务器。

仅通过服务器端代码无法做到这一点

【讨论】:

  • 这是一个 JavaFX 问题:一切都是客户端。
  • 可能不涉及物理 Web 服务器,但客户端-服务器架构仍然存在。
  • 不一定。这可以是一个常规的桌面应用程序,例如,加载到 WebView 中的 HTML 可以是应用程序 jar 文件中的静态资源。无论如何,我认为 OP 正在寻找在 JavaFX 代码中跟踪 DIV 元素的鼠标悬停,这绝对不在服务器上。
猜你喜欢
  • 2015-08-17
  • 2012-11-19
  • 2019-12-19
  • 2015-09-03
  • 1970-01-01
  • 2010-12-24
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多