在WebEngine中执行JavaScript时,如何在任何延迟脚本执行结果后使用WebEngine.getDocument
获取DOM?这是展示问题的最小代码。
在标准浏览器中呈现时,以下HTML执行以下操作:
以下是起始HTML:
<html>
<head>
<script>var y=document.createElement('script');
y.src = 'http://example.com/js/bar.js';
document.head.appendChild(y);
</script>
</head>
<body>
</body>
</html>
以下是out-of-line脚本bar.js包含的内容:
var x=document.createElement('div'); x.id='bar'; document.body.appendChild(x);
在标准浏览器中执行上述HTML之后,这就是DOM在真实浏览器中的样子,但这不是我在WebEngine中所获得的(我稍后会展示):
<html>
<head>
<script>var y=document.createElement('script'); y.src = 'http://example.com/js/bar.js'; document.head.appendChild(y);</script>
<script src="http://example.com/js/bar.js"></script>
</head>
<body>
<div id="bar"></div>
</body>
</html>
我试图使用无头JavaFX WebEngine使用以下代码模拟上述代码(这是完整的Java 8代码,减去导入):
public class StackOverflowQuestion extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
webEngine.setJavaScriptEnabled(true);
webEngine.loadContent("<html><head></head><body></body></html>");
webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener() {
@Override public void changed(ObservableValue o,Object oldVal, Object newVal) {
if (newVal == State.SUCCEEDED) {
webEngine.executeScript("var y=document.createElement('script'); y.src = 'http://example.com/js/bar.js'; document.head.appendChild(y);");
Document document = webEngine.getDocument();
printDOM(document);
} else {
System.out.println("Did not succeed");
}
}
});
}
private void printDOM(Document document) {
Transformer transformer;
try {
transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "html");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(new DOMSource(document), new StreamResult(new OutputStreamWriter(System.out, "UTF-8")));
} catch (Exception e) {
e.printStackTrace();
}
}
static public void main(String [] args) {
try {
Application.launch(args);
} catch (Exception e) {
e.printStackTrace();
}
}
}
以上代码输出以下DOM结构。请注意,DOM包含executeScript
调用的结果,但不包含外部脚本生成的结果。如何让DOM包含带有id bar的动态添加的div元素?
<HTML xmlns="http://www.w3.org/1999/xhtml">
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<SCRIPT src="http://example.com/js/bar.js"></SCRIPT>
</HEAD>
<BODY></BODY>
</HTML>