当我测试这个示例程序时,webview不能正确显示html页面。
- 第一页(第一圈)显示正确!但是…
- 应该每隔10秒换一个页面,但是没有。
- 它应该显示图形(当你点击第二个圆圈时),它没有。
- 它应该显示显示图像(当你点击第三圈时),它没有。
这里是我的配置:openjdk-17
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-web</artifactId>
<version>17.0.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.0.1</version>
</dependency>
<<p>代码/em>import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.StageStyle;
public class Main extends Application {
@Override
public void start(final Stage pStage) {
WebView lWebView = new WebView();
lWebView.getEngine().setJavaScriptEnabled(true);
lWebView.getEngine().load("http://it-topics.com/index3.html");
VBox lVBox = new VBox(lWebView);
pStage.setScene(new Scene(lVBox));
pStage.show();
}
public static void main(String[] args) {
launch();
}
}
我的总体观点是使webview像浏览器一样工作。有办法解决第2、3和4点吗?
测试环境背景
我进行了一些实验,以确定是什么原因导致(至少部分)您所提供的页面显示问题。
在我的测试中,我使用JavaFX 17.0.0.1运行Eclipse Temurin 17 JDK和Windows 10 Pro OS在MS Surface Book 2上。
从你的问题的示例网页显示在Chrome 94没有你在你的问题中注意到的问题,并在JavaFX WebView经历了你在你的问题中注意到的问题。
为了调试这个问题,我在web引擎中添加了一个控制台侦听器,如最流行的答案所示:
- 如何获得JavaFx WebEngine报告错误的详细信息?
- WebConsoleListener IllegalAccessError在JavaFX 12
一旦我这样做了,我看到以下错误记录到控制台:
Console: [https://cdn.jsdelivr.net/npm/chart.js:13] ReferenceError: Can't find variable: ResizeObserver
关于ResizeObserver的信息
做一些研究,我可以看到ResizeObserver实现并不是对所有浏览器实现都可用。所以我猜它没有在WebView中实现。
来自Mozilla的ResizeObserver信息
- https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
来自Mozilla的ResizeObserver示例测试页面(示例中奇怪的文本消息我不负责):
- https://mdn.github.io/dom-examples/resize-observer/resize-observer-text.html
在WebView中从mozilla加载示例页面确认了缺乏对ResizeObserver支持的问题,当附加WebConsoleListener时打印以下错误:
控制台:[https://mdn.github.io/dom-examples/resize-observer/resize-observer-text.html:110]不支持调整观察者大小!
如何修复
你可以通过polyfill为WebView(或其他不支持该功能的浏览器)添加ResizeObserver功能。
修复它的最好方法是请求你正在使用的网站的开发人员将ResizeObserver的polyfill集成到他们的网站中,以允许它在更广泛的客户端上使用。
修复这个问题的一个例子是:
- ResizeObserver polyfill。
如果你下载了你正在使用的网站的源代码,并在其他项目之前在页面中导入polyfill JavaScript,那么,你在问题中引用的大多数问题都会消失,并按预期在WebView上工作:
- 控制台没有显示关于ResizeObserver的错误。
- 显示每10秒自动更换一次。
- 点击第二个圆显示图形。
- 一个图像显示,当你点击第三个圆圈(虽然图像比我看到的Chrome和剪辑)。
ResizeObserver的Polyfill javascript源码:
- https://github.com/que-etc/resize-observer-polyfill/blob/master/dist/ResizeObserver.js
为JavaFX WebView提交ResizeObserver支持的特性请求
如果你愿意,你可以为JavaFX WebView提交一个特性请求,请求支持调整观察者的大小。
要做到这一点,你可以订阅openjfx-dev邮件列表并在那里发布关于这个问题的消息,链接到这个问题。
或者,向JavaFX提交一个bug报告。如果你这样做,我建议你参考mozilla resize observer测试页面和相关文档,而不是参考你原来问题中的测试页面。
<<p>测试代码/strong>必须使用来自:this answer的信息来运行,以允许访问内部com.sun.javafx
实现。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import com.sun.javafx.webkit.WebConsoleListener;
public class WebViewPageLoad extends Application {
@Override
public void start(final Stage stage) {
WebView webView = new WebView();
WebEngine engine = webView.getEngine();
engine.getLoadWorker().exceptionProperty().addListener((ov, t, t1) ->
System.out.println("Received exception: "+t1.getMessage())
);
WebConsoleListener.setDefaultListener((webViewReference, message, lineNumber, sourceId) ->
System.out.println("Console: [" + sourceId + ":" + lineNumber + "] " + message)
);
// test page from original question:
engine.load("http://it-topics.com/index3.html");
// test page for resize observer polyfill (functions as expected).
// engine.load("https://que-etc.github.io/resize-observer-polyfill/");
// canonical ResizeObserver test page from mozilla.
// engine.load("https://mdn.github.io/dom-examples/resize-observer/resize-observer-text.html");
// referencing a local hacked version of the it-topics.com index3.html.
// engine.load(WebViewPageLoad.class.getResource("it.html").toExternalForm());
VBox layout = new VBox(webView);
stage.setScene(new Scene(layout));
stage.show();
}
public static void main(String[] args) {
launch();
}
}