当前位置: 首页 > 知识库问答 >
问题:

为什么JavaScript方法在从JavaFX插入DOM时不执行?

冯祺
2023-03-14

我有一个大量使用WebView的JavaFX应用程序。我正在尝试向DOM中插入一个JavaScript代码可以使用的对象,并且我需要这些对象在加载新页面时可用。

但是,当我运行程序时,FirebugLite在DOM中显示了对象,但是函数没有执行。

根据Oracle的一些文档,这似乎是提供从JavaScript到Java的向上调用的适当方式。我也看到过一些StackOverflow的帖子解释了同样的事情。

Java:

public class DemoApplication extends Application {

    Debug debug;

    @Override
    public void start(final Stage stage) throws Exception {
        debug = new Debug();

        WebView browser = new WebView();
        WebEngine webEngine = browser.getEngine();
        webEngine.getLoadWorker().stateProperty().addListener(
                new ChangeListener<Worker.State>() {
                    @Override
                    public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) {
                        if (newValue == Worker.State.SUCCEEDED) {
                            JSObject windowObject = (JSObject) webEngine.executeScript("window");
                            windowObject.setMember("Debug", debug);
                        }
                    }
                }
        );
        webEngine.load("http://localhost:8080/page1.html");

        stage.setScene(new Scene(browser));
        stage.show();
    }

}

public class Debug {
    public void print(final Object text) {
        System.err.println(text);
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
  <script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script>
  <script>
    Debug.print("Hello");
  </script>
</head>
<body>
  Page 1
  <a href="page2.html">Page 2</a>
</body>
</html>

Firebug截图:

共有1个答案

谢阳曜
2023-03-14

我相信正在发生的是WebEngine加载页面,ChangeListener在不同的点(排定、运行、成功等)被调用。一旦Worker.State.Succeed事件发生,页面就已经完成了所有内容的加载并完成了该内容的执行。因此,基本上我在JavaScript代码中对debug.print()的调用是早期发生的,并且调用的对象是未定义的或空的。

无论如何,这是我最好的猜测,因为如果我添加一个JavaScript函数,在添加对象之后由Java部分执行,那么一切都将按照预期工作。

这就是我修改JavaScript端的方式:

<script>
  // callback that uses java objects
  window.ready = function() { 
    Debug.print("Hello");
  }
</script>
webEngine.getLoadWorker().stateProperty().addListener(
    new ChangeListener<Worker.State>() {
        @Override
        public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) {
            if (newValue == Worker.State.SUCCEEDED) {
                JSObject windowObject = (JSObject) webEngine.executeScript("window");
                windowObject.setMember("Debug", debug); // insert object
                windowObject.call("ready"); // execute callback
            }
        }
    }
);
 类似资料:
  • 我编写了以下代码来实现BST的递归插入方法。但是当我以遍历顺序打印树时,它会在插入之前打印原始树。似乎没有插入元素。请帮帮我。提前谢谢。另外,请建议更改代码。顺便说一下,初始树的遍历顺序是2 5 6 7 8。

  • 问题内容: 我正在尝试使用编写一个简单的代码,但是只是不愿等待它假定的时间而代码立即执行。我究竟做错了什么? 问题答案: 您正在立即调用该函数并计划其返回值。 使用: 注意:没有原谅。

  • 我遇到了这段代码,不知道为什么X在这里工作。

  • 问题内容: 我看过类似的帖子,但找不到答案,就我而言,我正试图通过以下方式采取行动: 到路线在那里我渲染组件 链接已呈现,但是当我单击它时,控制台出现错误: 为什么会这样,这里的解决方法是什么? 我更新的代码: Index.js中的路由: App.js: 问题答案: 首先 ,为您的函数添加一些默认值: 然后 使用: 或 尝试以下 方法 ( 更好的方法 ): 在next()组件中,使用传递的值,如下

  • 这是另一个非常经典的 java 多线程面试问题,而且在面试中会经常被问到。很简单,但是很多人都会答不上来! new 一个 Thread,线程进入了新建状态。调用 start() 方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。 start() 会执行线程的相应准备工作,然后自动执行 run() 方法的内容,这是真正的多线程工作。 而直接执行 run() 方法,会把 r

  • 问题内容: IAM尝试为BST类实现递归插入节点方法 我试图像这样调用此方法: 但是我总是得到以下输出: Node是BT的内部类。 经过数小时的运行和尝试其他事情,我无法弄清楚我在做什么错。 问题答案: 从您显示的代码来看,我的钱在这里的错误上: 实际上是对所引用对象的单独引用,因此用另一个值替换不会更改方法外的引用。您可以在方法内部修改引用的数据,但不能修改引用本身。