在loadworker成功之前触发javaFX webview window.onload [英] javaFX webview window.onload is fired before loadworker succeeds

查看:916
本文介绍了在loadworker成功之前触发javaFX webview window.onload的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中使用JavaFX webview。使用以下代码,我在页​​面加载后设置了一个成员

I use a JavaFX webview in my application. With the following code I set a member after the page has been loaded

webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
    @Override
    public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
        if (newState == Worker.State.SUCCEEDED) {
            JSObject window = (JSObject) webEngine.executeScript("window");
            window.setMember("mymember", new JavaScriptBridge(this));
        }
    }
});

现在在javascript中我可以调用 mymember.doSomething()例如当我按下按钮并且它已成功执行时调用,但如果我将以下代码添加到html

Now in javascript I can invoke mymember.doSomething() e.g. called when I press the button and it's executed successfully, but if I add the following code to the html

<script>
function startup() {
    mymember.doSomething();
}
window.onload=startup;
</script>

加载页面时不会自动执行。似乎 window.onload LoadWorker 收到通知之前执行。所以 mymember 尚未设置。但另一方面,在加载html之前,我无法设置 mymember ,对吗?

It's not executed automatically when the page is loaded. It seems like window.onload is executed before the LoadWorker gets notified. So mymember is not set yet. But on the other hand, I cannot set mymember before the html has been loaded, right?

任何想法何时我需要设置 mymember 以便在 window.onload 执行时准备好吗?

Any idea when I need to set mymember to have it ready when window.onload is executed?

谢谢!

推荐答案

对于这个问题的答案可能为时已晚,但在回答这个问题,我一直试图找到 executeScript 。

Maybe it's too late for an answer to this problem, but after answering this question, I've been trying to find a reason why executeScript has to be called after the complete load of the webpage.

所以我做了这个测试:

    public class EarlyWebEngineTest extends Application {

    @Override
    public void start(Stage stage) {
        final WebView webView = new WebView();
        final WebEngine webEngine = webView.getEngine();

        // Early call of executeScript to get a JavaScript object, a proxy for the 
        // Java object to be accessed on the JavaScript environment
        JSObject window = (JSObject) webEngine.executeScript("window");
        window.setMember("app", new JavaApplication());

        webEngine.getLoadWorker().stateProperty().addListener((ov,oldState,newState)->{
            if(newState==State.SCHEDULED){
                System.out.println("state: scheduled");
            } else if(newState==State.RUNNING){
                System.out.println("state: running");
            } else if(newState==State.SUCCEEDED){
                System.out.println("state: succeeded");
            }
        });

        Button button=new Button("Load Content");
        button.setOnAction(e->webEngine.loadContent("<html>"
                + " <script>function initialize() {"
                + " var nameVar = \"This is a JS var\"; " 
                + " app.callJavascript(nameVar);"
                + "} </script>"
                + "    <body onLoad=\"initialize()\">Hi, this is a test!</body>"
                + "</html>"));

        VBox vbox = new VBox(10,button,webView);
        Scene scene = new Scene(vbox,400,300);

        stage.setScene(scene);
        stage.show();

    }

    public class JavaApplication {

        public void callJavascript(String msg){
            System.out.println("JS>> "+msg);
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

}

直到单击按钮,但我们已经在浏览器上创建了JavaScript对象。

The content is not loaded until the button is clicked, but we've already created the JavaScript object on the browser.

在单击按钮之前,输出控制台上没有任何内容。但是如果我们点击按钮......这就是输出:

Before clicking the button, there's nothing on the output console. But if we click the button... this is the output:

state: scheduled
state: running
JS>> This is a JS var
state: succeeded

正如我们所看到的,Java对象是在执行后者之前有效地传递给脚本,并且在加载内容时成功调用 app.callJavascript

As we can see, the Java object is effectively passed to the script before the latter is executed, and app.callJavascript is successfully called while the content is being loaded.

请注意,出于访问加载的DOM的常见目的,在 State.SUCCEEDED executeScript 的常用方法>仍然是推荐的方式。

Note that for the common purpose of accessing the loaded DOM, the usual approach of calling executeScript after State.SUCCEEDED is still the recommended way.

这篇关于在loadworker成功之前触发javaFX webview window.onload的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆