为什么 JavaScript 方法在从 JavaFX 插入 DOM 时不执行?
Why doesn't the JavaScript method execute when inserted into the DOM from JavaFX?
我有一个 JavaFX 应用程序,它大量使用 WebView。我正在尝试将对象插入到 DOM 中,Java 脚本代码可以使用,并且我需要这些对象在加载新页面时可用。
但是,当我运行程序时,FirebugLite显示DOM中的对象,但函数不执行。
根据some Oracle documentation, this seems to be the appropriate way to provide upcalls from JavaScript to Java. I've also seen a few Whosebug posts解释同样的事情。
我错过了什么?我在 Windows 7.
上使用 Java 8,更新 51,64 位
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截图:
我相信正在发生的事情是 WebEngine 加载了页面,ChangeListener 在不同的时间点被调用(SCHEDULED、运行、SUCCEEDED 等)。一旦 Worker.State.SUCCEEDED 事件发生,页面就已经完成了所有内容的加载,并且已经完成 执行该内容 。所以基本上我在 Java 脚本代码中对 Debug.print() 的调用很早就发生了,并且调用了一个 undefined 或 null[ 的对象=29=]。
无论如何,这是我最好的猜测,因为如果我添加一个 JavaScript 函数,该函数由 Java 部分执行 after 添加对象,一切正常。
这是我修改Java脚本端的方式:
<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
}
}
}
);
此处的关键变化是 Java脚本中的 ready() 函数,并在 之后调用该函数 在 Java 侧注入对象.这确保这些对象在被调用之前可用。
我在几个不同的页面上尝试过这个,当从一个页面转到另一个页面时,当调用 ready() 函数时 Debug.print() 正确执行,即使在使用 WebEngine.reload() 时,或 WebHistory.go().
我有一个 JavaFX 应用程序,它大量使用 WebView。我正在尝试将对象插入到 DOM 中,Java 脚本代码可以使用,并且我需要这些对象在加载新页面时可用。
但是,当我运行程序时,FirebugLite显示DOM中的对象,但函数不执行。
根据some Oracle documentation, this seems to be the appropriate way to provide upcalls from JavaScript to Java. I've also seen a few Whosebug posts解释同样的事情。
我错过了什么?我在 Windows 7.
上使用 Java 8,更新 51,64 位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截图:
我相信正在发生的事情是 WebEngine 加载了页面,ChangeListener 在不同的时间点被调用(SCHEDULED、运行、SUCCEEDED 等)。一旦 Worker.State.SUCCEEDED 事件发生,页面就已经完成了所有内容的加载,并且已经完成 执行该内容 。所以基本上我在 Java 脚本代码中对 Debug.print() 的调用很早就发生了,并且调用了一个 undefined 或 null[ 的对象=29=]。
无论如何,这是我最好的猜测,因为如果我添加一个 JavaScript 函数,该函数由 Java 部分执行 after 添加对象,一切正常。
这是我修改Java脚本端的方式:
<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
}
}
}
);
此处的关键变化是 Java脚本中的 ready() 函数,并在 之后调用该函数 在 Java 侧注入对象.这确保这些对象在被调用之前可用。
我在几个不同的页面上尝试过这个,当从一个页面转到另一个页面时,当调用 ready() 函数时 Debug.print() 正确执行,即使在使用 WebEngine.reload() 时,或 WebHistory.go().