【问题标题】:How to catch return value from javascript in javafx?如何从 javafx 中的 javascript 捕获返回值?
【发布时间】:2015-05-22 16:29:55
【问题描述】:

我正在我的 JavaFX 应用程序的 web 视图中执行 javascript 代码。每当单击鼠标时,我都需要让它重复执行,并将元素详细信息放入 java 变量中。我正在使用下面的代码并使用 Firebug Lite。在 Firebug 控制台中,需要的项目正在打印。但我希望它返回到 java 应用程序。

engine.documentProperty().addListener(new ChangeListener<Document>() {
            @Override public void changed(ObservableValue<? extends Document> prop, Document oldDoc, Document newDoc) {
                enableFirebug(engine);
                Object obj=engine.executeScript("var lastElement = null; "
                        + "document.addEventListener('click', function(e) {"
                        + "if (e.target != lastElement) {"
                        + "lastElement = e.target;"
                        + "console.log(lastElement.name);"
                        + "return lastElement.name;"
                        + "}}, false);");
                System.out.println(obj.toString());
            }
        });

它在页面加载时执行,但不是在每次鼠标单击后执行。请建议我如何修改它。

【问题讨论】:

  • 您希望用户每次点击页面上的任何内容?
  • 是的@EvanKnowles,每次用户点击一个元素时,我都想获取元素 ID/名称。

标签: javascript javafx javafx-webengine


【解决方案1】:

尝试反过来调用它。假设您将页面加载为

final WebEngine webEngine = webview.getEngine();
webEngine.load("http://localhost/demo/clickHandler/");

我们将为成功状态设置一个监听器 - 基本上我们将向 JavaScript 中注入一个 Java 类并让它回调我们。让我们创建一个 WebController 来检查传入的内容并打印出 ID:

public class WebController {
    public void printId(Object object) {
        if (org.w3c.dom.html.HTMLElement.class.isAssignableFrom(object.getClass())) {
            org.w3c.dom.html.HTMLElement it = (org.w3c.dom.html.HTMLElement) object;
            System.out.println("Id is " + it.getId());
        }
    }
}

现在加载成功后,我们将其作为clickController 注入到应用程序中。

    webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
          @Override
          public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
              if (newState == State.SUCCEEDED) {
                  JSObject window = (JSObject) webEngine.executeScript("window");
                  window.setMember("clickController", new WebController());
              }
          }
      }
    );

现在我们需要页面上的一些 JavaScript 来回调我们。假设您使用的是 jQuery,请将此代码添加到您的页面:

$(function () {
    $('*').click(function (event) {
        event.preventDefault();
        event.stopPropagation();
        clickController.printId(this);
    });
});

现在,当单击任何内容时,将回调webController,它将检查对象是否为HTMLElement 并打印出其 ID(如果没有 ID,则为 null)。

不使用 jQuery 会有点困难,但您可以将其添加到文档的末尾:

var nonJQuery = function (event) {
    clickController.printId(this);
    event.preventDefault();
    event.stopPropagation();
};
var elements = document.querySelectorAll("*");
for (var i = 0; i < elements.length; i++) {
    elements[i].addEventListener("click", nonJQuery, false);
}

如果无法向文档添加内容,您可以执行脚本以在成功的函数中添加点击处理程序。更新成功的函数如下所示:

    webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
          @Override
          public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
              if (newState == State.SUCCEEDED) {
                  JSObject window = (JSObject) webEngine.executeScript("window");
                  webEngine.executeScript("var nonJQuery = function (event) {\n" +
                          "    clickController.printId(this);\n" +
                          "    event.preventDefault();\n" +
                          "    event.stopPropagation();\n" +
                          "};\n" +
                          "var elements = document.querySelectorAll(\"*\");\n" +
                          "for (var i = 0; i < elements.length; i++) {\n" +
                          "    elements[i].addEventListener(\"click\", nonJQuery, false);\n" +
                          "}");
                  window.setMember("clickController", new WebController());
              }
          }
      }
    );

最后,如果您想阻止页面导航,例如。从链接中,您可以将 return false; 添加到 JavaScript:

    webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
          @Override
          public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
              if (newState == State.SUCCEEDED) {
                  JSObject window = (JSObject) webEngine.executeScript("window");
                  webEngine.executeScript("var nonJQuery = function (event) {\n" +
                          "    clickController.printId(this);\n" +
                          "    event.preventDefault();\n" +
                          "    event.stopPropagation();\n" +
                          "    return false;\n" +
                          "};\n" +
                          "var elements = document.querySelectorAll(\"*\");\n" +
                          "for (var i = 0; i < elements.length; i++) {\n" +
                          "    elements[i].addEventListener(\"click\", nonJQuery, false);\n" +
                          "}");
                  window.setMember("clickController", new WebController());
              }
          }
      }
    );

【讨论】:

  • 感谢您的回答。我没有使用 jQuery。是否可以仅使用 javascript 来执行此操作?如何修改最后一段代码?
  • @naveenbharadwaj 我添加了一个非 jQuery 版本。
  • 你的意思是把它添加到 HTML 文档中?我将在 webView 中加载不同的网站,而不是一个 HTML 文档
  • 变化来了,一会儿。
  • 非常感谢..我有最后一个查询..如果我点击任何链接,我只需要获取详细信息而不是重新加载页面..有可能这样做吗?例如,我单击一个链接以获取 ID。它返回 ID,但页面被重定向。我不希望这种情况发生。
猜你喜欢
  • 1970-01-01
  • 2014-01-23
  • 2016-04-23
  • 2016-09-09
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
相关资源
最近更新 更多