我创建的页面将在WebView中从Java打开,或者在外部浏览器中手动打开。如果页面是从Java加载的 - 我需要它来执行特定的回调,因为Java被用作后端的一种,但如果页面是手动加载的,它应该从其资源加载不同的数据。所以我试图注册JS" JavaInit"可以在文档加载时调用的对象。 HTML看起来像这样:
<html>
<head>
<script type='text/javascript' src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script type="text/javascript">
DefaultInit = {
init: function(x) {
return "Default init: " + x;
}
};
$(function() {
var text;
if (window["JavaInit"] && JavaInit.init)
text = JavaInit.init("passed text");
else
text = DefaultInit.init("passed text");
$("#title").html(text);
});
</script>
</head>
<body>
<h1 id="title"></h1>
</body>
</html>
我已经在这里阅读了有关在页面onload事件之前设置JS成员的问题:javaFX webview window.onload is fired before loadworker succeeds,所以我的Java代码如下所示:
public class Test extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
WebView web = new WebView();
Scene scene = new Scene(web, 400, 300);
primaryStage.setScene(scene);
primaryStage.show();
initWeb(web);
}
private static void initWeb(WebView web) {
WebEngine eng = web.getEngine();
((JSObject)eng.executeScript("window")).setMember("JavaInit", new JavaInit());
URL url = Test.class.getResource("/test.html");
eng.load(url.toString());
}
public static class JavaInit {
public String init(Object o) {
return "Java init: " + o;
}
}
}
它完全按照要求工作,但只有一次,在任何人打电话之前#34;重新加载页面&#34;。重装后引擎似乎重新创建了&#34;窗口&#34;对象和所有注册成员都消失了。
可以将#setMember放在&#34; state属性&#34;监听器:
private static void initWeb(WebView web) {
WebEngine eng = web.getEngine();
eng.getLoadWorker().stateProperty().addListener((val, oldState, newState) -> {
if (newState == State.SUCCEEDED)
((JSObject)eng.executeScript("window")).setMember("JavaInit", new JavaInit());
});
URL url = Test.class.getResource("/test.html");
eng.load(url.toString());
}
但是只有在window.onload被触发后才调用它,并且一直调用默认的init。可以通过以最小延迟调用init代码来解决这个问题:
$(function() {
setTimeout(function() {
var text;
if (window["JavaInit"] && JavaInit.init)
text = JavaInit.init("passed text");
else
text = DefaultInit.init("passed text");
$("#title").html(text);
});
});
然后控制从JS处理回Java(如果存在),然后返回到注册函数,并且programm每次都正常工作。
但似乎有点不对,要创建init延迟,希望Java能成功注册所有成员。所以任何人都知道任何更合适的&#34;实现这种功能的方法?是否有可能在生产中需要更多时间,JS可以在成员注册之前调用延迟功能?或者是否有任何保证WebEngine将持续处理Java事件和JS执行?
谢谢!
答案 0 :(得分:1)
我有同样的问题,我需要设置成员才能在JS中触发onload事件。我在标题中添加了JS中的警告:
alert("command:inject");
在Java代码中:
webEngine.setOnAlert(new EventHandler<WebEvent<String>>() {
@Override
public void handle(WebEvent<String> event) {
// set members here
}
});
所以看起来,在同步运行的警报句柄上,所以当onload将触发时将启动的脚本将看到在警报处理程序中设置的成员