2015-08-27 5 views
5

У меня есть приложение JavaFX, которое сильно использует WebView. Я пытаюсь вставить объект в DOM, который может использовать код JavaScript, и мне нужно, чтобы эти объекты были доступны при загрузке новых страниц.Почему метод JavaScript не выполняется при вставке в DOM из JavaFX?

Однако, когда я запускаю программу, FirebugLite показывает объект в DOM, но функции не выполняются.

Согласно some Oracle documentation, это, по-видимому, является подходящим способом обеспечения восходящего потока от JavaScript до Java. Я также видел несколько StackOverflow posts, объясняющих одно и то же.

Что мне не хватает? Я использую Java 8, Update 51, 64-бит на ОС Windows 7.

Java:

public class DemoApplication extends Application { 

    Debug debug; 

    @Override 
    public void start(final Stage stage) throws Exception { 
     debug = new Debug(); 

     WebView browser = new WebView(); 
     WebEngine webEngine = browser.getEngine(); 
     webEngine.getLoadWorker().stateProperty().addListener(
       new ChangeListener<Worker.State>() { 
        @Override 
        public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) { 
         if (newValue == Worker.State.SUCCEEDED) { 
          JSObject windowObject = (JSObject) webEngine.executeScript("window"); 
          windowObject.setMember("Debug", debug); 
         } 
        } 
       } 
     ); 
     webEngine.load("http://localhost:8080/page1.html"); 

     stage.setScene(new Scene(browser)); 
     stage.show(); 
    } 

} 

public class Debug { 
    public void print(final Object text) { 
     System.err.println(text); 
    } 
} 

HTML/JavaScript:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title></title> 
    <script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script> 
    <script> 
    Debug.print("Hello"); 
    </script> 
</head> 
<body> 
    Page 1 
    <a href="page2.html">Page 2</a> 
</body> 
</html> 

Firebug Скриншот:

enter image description here

ответ

3

Я верю, что происходит то, что WebEngine загружает страницу, ChangeListener находится в (ЗАПЛАНИРОВАНО, РАБОТАЮТ, УСПЕШНО и т. д.). Как только произойдет событие Worker.State.SUCCEEDED, страница уже завершила загрузку всего содержимого и завершила , выполнив этот контент, а также. Поэтому в основном мои вызовы Debug.print() в коде JavaScript происходили раньше и вызывали объект, который был undefined или null.

Это мое лучшее предположение, так как если я добавлю функцию JavaScript, выполняемую частью Java после добавления в объекты, все работает так, как ожидалось.

Это, как я изменил сторону JavaScript:

<script> 
    // callback that uses java objects 
    window.ready = function() { 
    Debug.print("Hello"); 
    } 
</script> 

И это, как я изменил стороне Java:

webEngine.getLoadWorker().stateProperty().addListener(
    new ChangeListener<Worker.State>() { 
     @Override 
     public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) { 
      if (newValue == Worker.State.SUCCEEDED) { 
       JSObject windowObject = (JSObject) webEngine.executeScript("window"); 
       windowObject.setMember("Debug", debug); // insert object 
       windowObject.call("ready"); // execute callback 
      } 
     } 
    } 
); 

Основные изменения здесь находятся готовые функции() в JavaScript , и вызывая эту функцию после, вводя объекты на стороне Java. Это гарантирует, что эти объекты доступны перед вызовом.

Я пробовал это на нескольких разных страницах и при переходе со страницы на страницу, когда функция ready() была вызвана Debug.print() правильно, даже при использовании WebEngine.reload() или WebHistory.go ().

 Смежные вопросы

  • Нет связанных вопросов^_^