以下代码适用于Linux,但回调在Windows(VirtualBox VM)上不起作用。你能告诉我为什么吗?
爪哇:
public class WebViewTest extends Application {
private Label label = new Label ("...");
public static void main (String[] args) {
launch (args);
}
@Override
public void start (Stage stage) throws Exception {
WebView webView = new WebView ();
WebEngine webEngine = webView.getEngine ();
webEngine.setJavaScriptEnabled (true);
JSObject window = (JSObject) webView.getEngine ().executeScript ("window");
window.setMember ("java", new Callback ());
webEngine.load (getClass ().getResource ("WebViewTest.html").toString ());
BorderPane pane = new BorderPane ();
pane.setCenter (webView);
pane.setBottom (label);
Scene scene = new Scene (pane);
stage.setScene (scene);
stage.show ();
}
public class Callback {
public void click () {
label.setText ("Clicked :-)");
}
}
}
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta charset="UTF-8">
</head>
<body>
<button onclick="window.java.click ();">Test</button>
</body>
</html>
答案 0 :(得分:4)
诀窍是将Callback创建为类字段:
private Callback callback = new Callback ();
然后:
webEngine.load (getClass ().getResource ("WebViewTest.html").toString ());
JSObject window = (JSObject) webView.getEngine ().executeScript ("window");
// BUG // window.setMember ("java", new Callback ());
window.setMember ("java", callback);
也许在Windows上有一些垃圾收集?我不知道......
答案 1 :(得分:0)
当新的DOM加载到Web引擎中时,window
对象可能会被替换。尝试在加载文档时设置回调:
Callback callback = new Callback();
webEngine.documentProperty().addListener((obs, oldDoc, newDoc) -> {
if (newDoc != null) {
JSObject window = (JSObject) webView.getEngine ().executeScript ("window");
window.setMember ("java", callback);
}
});
(您可以看到window
对象在加载HTML之前按System.out.println(System.identityHashCode(webView.getEngine ().executeScript ("window"))
更改,并在文档侦听器中更改System.out.println(System.identityHashCode(window))
。)
答案 2 :(得分:0)
我遇到了类似的问题,在深入研究之后,我发现您应该在渲染html后调用window.setMember ("java", new Callback ());
,这样就可以了:
JSObject window = (JSObject) webView.getEngine ().executeScript ("window");
webEngine.load (getClass ().getResource ("WebViewTest.html").toString ())
window.setMember ("java", new Callback ());
还请注意,如果执行重新加载或导航到另一页,则会再次失去功能。一个可靠的解决方案是:
webEngine.documentProperty().addListener(((observable, oldValue, newValue) -> {
if (Objects.nonNull(newValue)) {
JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("engine", callback);
}
}));