我正在编写一个JavaFX应用程序,它与JavaScript交互,使用WebView和WebEngine(.executeScript()方法)。
在这里,我有Medow.java的这部分代码,它加载了map.html(包含JavaScript代码),而且这段代码工作得很好:
add_button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent ea5) {
// webEngine.executeScript("document.fun();"); // For Drawing Shapes
if (add == false) {
webEngine.executeScript("document.fun();"); // For Drawing Shapes
add = true;
}
// }
else {
webEngine.executeScript("document.reSet();"); // To remove Drawing Shapes
add = false;
}
}
});
在这里
webEngine.executeScript();
正在调用适当的JavaScript函数
但是现在,我希望我的Java代码调用一些JS函数,当程序启动时,所以我直接写了:
webEngine.executeScript("document.draw();");
在代码之下/之后,加载map.html文件。
所以,现在作为两者之一
webEngine.execute("document.fun();");
和webEngine.executeScript("document.draw();");
几乎相似,我无法理解差异的作用,它会在<button>.setOnAction
块内部并且在它之外,因为WebEngine和webView都被声明为全局变量
无法使用HTML的onLoad选项调用document.draw()函数,因为我需要传递一些值来从java中绘制函数。
生成的异常是:
netscape.javascript.JSException: TypeError: undefined is not a function (evaluating 'document.draw()')
我该怎么做才能做到这一点?谢谢
虽然不断尝试弄清楚原因是什么,但我发现使用webEngine.load()
创建的HTMLDocument对象由于某种原因仅在handle方法中可见,而在其他任何地方都没有,即使它已在外部定义。
答案 0 :(得分:4)
这里发生的是你想在完全加载内容之前调用JavaScript函数。因此,未定义函数draw
。所以唯一的方法是等到页面加载。有两种方法可能有用:
在状态上添加changelistener并在加载成功后执行JavaScript:
字符串htmlURL = ...
。webView.getEngine()负载(HTMLURL);
webView.getEngine().stateProperty().addListener(new ChangeListener<Worker.State>() {
@Override
public void changed(ObservableValue<? extends Worker.State> ov, Worker.State t, Worker.State t1) {
if (t1 == Worker.State.SUCCEEDED) {
// this will be run as soon as WebView is initialized.
webView.getEngine().executeScript("document.draw()");
}
}
});
另一种方式是JavaScript中的解决方案。首先必须在Java和html页面之间注册一个桥梁(必须在SUCCEEDED
状态更改中完成,请参阅WebView callback from Javascript):
JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("app", this);
现在,您的JavaScript中引用了此JavaObject。假设您在类上有一个类型为this
的方法:
public void executeOnPageLoaded() {
...
}
然后你可以从Javascript调用这个方法。如果您使用的是jQuery,它可能如下所示:
$( document ).ready(function() {
console.log( "ready!" );
app.executeOnPageLoaded();
});
第二种方法更复杂,但从长远来看可能会给你更大的灵活性。
当您在WebView中开始使用JavaScript时,最好还要在其中安装Firebug lite,因此请调查正在发生的事情,但主要是为了有机会为JavaScript的控制台输出提供种子。见Java FX application onload event