【问题标题】:WebView not reloading page with identical URLWebView 没有重新加载具有相同 URL 的页面
【发布时间】:2013-08-20 17:21:20
【问题描述】:

JavaFX 在加载与之前加载的页面具有相同 url 的页面时会显示一些奇怪的行为。下面的代码演示了这个问题:

类初始化后,页面被加载,然后使用自定义样式类将高亮应用于任意 html 元素。此高亮显示正确。

最后,通过用户输入事件,WebView 被告知加载一个新页面(具有相同的 URI)。不是按原样显示页面,而是显示突出显示。

WebView webView = new WebView();
static String URI = "http://www.example.com";

public void loadPage() {
    // Step 1: load page
    webView.getEngine().load(URI);

    // Step 2: Change style attribute in page
    (Element) element = xpath.evaluate("//div[@id='mydiv']", webView.getEngine().getDocument(), XPathConstants.NODE);
    element.setAttribute("class", "mystyle");
}

handle() {
    // Step 3: load page again
    webView.getEngine().load(URI);
}

我尝试过使用 WebView.getEngine().reload() 强制页面重新加载、禁用缓存、等待工作人员完成等。

我目前看到的唯一选择是创建 WebView 的新实例,但由于这会占用大量 CPU,因此我更喜欢重用该对象,而不是每次想要恢复到原始页面时都创建新的对象。

【问题讨论】:

  • “重建整个WebView”是什么意思?再次调用webView.getEngine().load("your url"); 就足够了。这就像一个网页的刷新。无需重新创建 webview 实例。
  • 我已经改写了我的文本,但是是的,因为它是我唯一可行的解​​决方案,每次我想重新加载我玩过的页面时,我都创建一个新的 webview 实例之前的 DOM 文档。看来 DOM 文档在 WebView 引擎内部被缓存。

标签: java webview javafx


【解决方案1】:

这是一个演示 HTML 内容重新加载的 SSCCE。它与您的方法有点不同,但故事是一样的,尽管没有尝试加载像您这样的外部 URL。您对 webEngine 的缓存是正确的,因为 webEngine.reload() 不会加载原始内容。

public class WebViewReload extends Application {

    private String content = "<html>"
            + "    <head>"
            + "         <style type=\"text/css\">"
            + "            .mystyle {"
            + "                padding: 20px;"
            + "                background-color: red;"
            + "                font-size: 30px;"
            + "            }"
            + "        </style>"
            + "    </head>"
            + "    <body>"
            + "        <div id=\"mydiv\">initial content</div>"
            + "    </body>"
            + "</html>";

    @Override
    public void start(final Stage stage) throws Exception {
        final WebView webView = new WebView();
        webView.getEngine().loadContent(content);
        // It is same as loading an external html source, like this
        // webView.getEngine().load(getClass().getResource("my.html").toExternalForm());

        Button btn1 = new Button("Apply style");
        btn1.setPrefWidth(200);
        btn1.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                Element element = webView.getEngine().getDocument().getElementById("mydiv");
                element.setAttribute("class", "mystyle");
                element.setTextContent("new content");
            }
        });

        Button btn2 = new Button("Reload content");
        btn2.setPrefWidth(200);
        btn2.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                webView.getEngine().loadContent(content);
                // following does not reload at all
                // webView.getEngine().reload();
            }
        });

        VBox vbox = new VBox(10);
        vbox.setPadding(new Insets(20));
        vbox.setStyle("-fx-background-color: gray");
        vbox.getChildren().addAll(webView, btn1, btn2);

        Scene scene = new Scene(vbox);
        stage.setScene(scene);
        stage.show();
    }

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

【讨论】:

  • 感谢您确认Uluk的问题。
  • @Stern。正如我之前所说,webView.getEngine().loadContent(content);(在上面的“重新加载内容”按钮中)会加载原始内容。我们同意吗?
  • 正确,并且由于 loadContent 需要重建 DOM 文档,因此也很有意义。我还在研究这个问题。我发现在 WebView 中的用户输入事件之后更新 DOM 文档实际上可以按预期工作。这样的事件似乎触发了对文档的内部审查。
猜你喜欢
  • 2020-08-12
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
  • 2019-09-13
  • 1970-01-01
  • 2014-04-03
  • 2015-12-22
  • 1970-01-01
相关资源
最近更新 更多