这并没有解决 OP 指出的所有细节,但可能对其他人有用。在 Chrome 97、Firefox 96、Android 11、iOS 15 中测试。
我有一个包含这些 CSS 参数的 div...
#div_image {
background-image: url( [Path to low-res image] );
background-size: cover;
}
我有一个对应的类,看起来像这样......
.div_image_highres {
background-image: none !important;
}
对应的类有一个伪元素定义如下:
.div_image_highres::before {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
content: " ";
background-image: url( [Path to highres image] );
background-repeat: no-repeat;
background-position: 50% 0;
background-size: cover;
opacity: 1;
display: block;
}
我有一个 img 元素也指向高分辨率图像...
<img id="img_highres_preload" src=" [Path to high-res image ] ">
img 元素有一个相应的样式,它允许图像显示(确保图像文件加载)但看不到...
#img_highres_preload {
width: 1px;
height: 1px;
}
两个注意事项:(1)我意识到很多人使用其他预加载方法(例如,以编程方式),但我个人偏爱这种方法。 (2) 加载事件的可靠性见附录。
最后但并非最不重要的一点是,一旦加载高分辨率文件,我有一些 Javascript (jQuery) 会将“高分辨率”类添加到“div_image”...
$(document).ready(function() {
$("#img_highres_preload").off().on("load", function() {
$("#div_image").addClass("div_image_highres");
});
});
这很容易成为普通 JS,但由于我在整个代码中使用 jQuery,我喜欢保持一致性。
这里是正在发生的事情的摘要......
- 大概是先加载低分辨率图像,然后成为 div 的背景图像。即使这没有发生,一切都会按预期工作(即,将显示高分辨率图像)。
- 当高分辨率图像加载到 img 元素中时(即 Javascript 确认加载了高分辨率文件),“div_image_highres”类将应用于“div_image”。
- 结果,div 切换到高分辨率图像而不闪烁。根据我的经验,如果有的话,它会向左移动一点。但这通常不会发生,即使发生了,也不是不雅。
- 这是我在需要时使用此方法的主要原因:在我的应用程序中,用户可以导航多个面板,这导致一个面板滑出视图而新的面板滑入视图。如果我不使用伪元素(如上所述)来显示高分辨率图像,则图像会在其 div 被隐藏并重新显示时闪烁。使用上述技术,我可以将 div 滑入和滑出视图,而不会出现任何闪烁。
关于加载事件
您不能依赖加载事件触发。例如,当浏览器缓存了图像时,它通常不会触发。因此,为了使长篇文章更长,这是我在代码中为适应这一现实而进行的增强...
我将 document.ready 事件(如上所示)修改为如下所示:
$(document).ready(function() {
positionOnPage(true);
$("#img_highres_preload").off().on("load", function() {
checkImage();
});
});
checkImage = function() {
var image = $("#img_highres_preload")[0];
if (!image.complete || (typeof image.naturalWidth != "undefined" && image.naturalWidth == 0)) {
console.log("Waiting for high-res image.");
}
else if (!$("#div_home").hasClass("div_home_highres")) {
$("#div_home").addClass("div_home_highres");
$("#img_highres_preload").remove();
}
}
checkImage 函数检查图像元素以查看图像是否实际上已加载。在这个代码示例中,它有点多余——即 img 元素已经确认加载,所以通常不需要检查它(除非有理由相信文件被错误加载)。
我可能会这样做,因为我还从代码中的其他地方调用 checkImage,所以如果我有更多的程序响应(与显示的简单版本不同),我希望所有代码在同一个地方并编写就一次。 checkImage 函数可能会在由计时器触发时或在显示预期图像的部分即将显示时被调用。也许是这样的......
if (sectionName == "[whatever]" && $("#img_highres_preload").length === 1) {
checkImage();
}
在此示例中,我查找预加载 img 元素的存在,因为我知道我之前的函数在完成其目的后删除了该元素。
这篇文章有一个精简的版本来说明这个概念。如上所述,它只容纳一个已知的 img 元素,因此可以扩展代码以使用一些参数(例如,图像的名称或元素本身)调用 checkImage,并且 checkImage 可以查找预加载元素的存在,以便检查发生在一个地方。它可能相当花哨,所以我为这篇文章选择了最简单的例子。
在许多情况下,我只需要这个精简版本,因为通常我只使用高分辨率照片作为窗口背景图像。我要么从显示低分辨率图像开始,并在加载高分辨率文件后立即将其关闭,要么在我确认存在高分辨率图像后触发一些动画。
更通用的版本的一个很好的例子是,当我需要一开始就加载一系列图像并且不想在所有图像都准备好之前开始。在这些情况下,网页可能会以一些欢迎文本开始,直到所有图像都得到确认。