Как поймать возвращаемое значение из javascript в javafx?

Я выполняю код javascript в своем веб-просмотре приложения JavaFX. Мне нужно, чтобы он выполнялся повторно всякий раз, когда есть щелчок мыши, и получаю детали элемента в переменную 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());
            }
        });

Он выполняется при загрузке страницы, но не после каждого щелчка мыши. Пожалуйста, предложите мне, как изменить его.


person NaveenBharadwaj    schedule 22.05.2015    source источник
comment
Вы хотите, когда пользователь нажимает на что-либо на странице?   -  person Evan Knowles    schedule 22.05.2015
comment
да @EvanKnowles, каждый раз, когда пользователь нажимает на элемент, я хочу получить идентификатор/имя элемента.   -  person NaveenBharadwaj    schedule 22.05.2015


Ответы (1)


Попробуйте назвать это наоборот. Предполагая, что вы загружаете свою страницу как

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

Мы собираемся установить прослушиватель для успешного состояния — по сути, мы собираемся внедрить класс Java в JavaScript, и он перезвонит нам. Давайте создадим WebController, который проверяет, что передается, и распечатывает идентификатор:

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, и распечатает его идентификатор (или 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());
              }
          }
      }
    );
person Evan Knowles    schedule 22.05.2015
comment
спасибо за Ваш ответ. Я не использую jQuery. Можно ли это сделать, используя только javascript? Как я могу изменить последний фрагмент кода? - person NaveenBharadwaj; 22.05.2015
comment
@naveenbharadwaj Я добавил версию без jQuery. - person Evan Knowles; 22.05.2015
comment
Вы имеете в виду добавление его в HTML-документ? Я буду загружать разные веб-сайты в webView, а не один HTML-документ. - person NaveenBharadwaj; 22.05.2015
comment
Изменения приходят, один момент. - person Evan Knowles; 22.05.2015
comment
большое спасибо.. У меня есть последний вопрос.. Если я нажму на любую ссылку, мне просто нужно получить подробности, а не перезагружать страницу.. Есть ли возможность сделать это? например, я нажимаю на ссылку, чтобы получить идентификатор. Он возвращает идентификатор, но страница перенаправляется. Я не хочу, чтобы это произошло. - person NaveenBharadwaj; 22.05.2015
comment
Эй, можно, но это явно нарушит функциональность страницы. Проверьте окончательное обновление. - person Evan Knowles; 22.05.2015
comment
Давайте продолжим это обсуждение в чате. - person NaveenBharadwaj; 22.05.2015