预加载隐藏的 CSS 图像
Posted
技术标签:
【中文标题】预加载隐藏的 CSS 图像【英文标题】:preload hidden CSS images 【发布时间】:2010-12-19 17:28:55 【问题描述】:我正在开发一个基于 jquery 的主页,其中包含 5 个左右隐藏的 div,每个 div 都包含几个背景 css 图像。
问题是浏览器在显示父层的可见性之前不会将 css 图像加载到 DOM 中,导致当该层变得可见时图像加载缓慢。
我已经考虑过的解决方案:
CSS sprites(为此重新设计的工作量太大,并且在显示/隐藏 div 时不会真正起作用) This jQuery plugin 自动加载 CSS 背景图像(正如许多其他人所报告的那样,对我来说根本不起作用)。通过js预加载图片:
$(function()
function preloadImg(image)
var img = new Image();
img.src = image;
preloadImg('/images/home/search_bg_selected.png');
);
此解决方案似乎将图像加载到 dom 中两次...一次在 js 加载它时,然后在加载它的 div 层变得可见时再次...所以它进行了 2 个 HTTP 调用,因此无法正常工作。
我还没有解决此问题的任何其他解决方案吗?
【问题讨论】:
【参考方案1】:当您说其他方式时,您是指不使用 javascript 的方式吗?
<script language="JavaScript">
function preloader()
// counter
var i = 0;
// create object
imageObj = new Image();
// set image list
images = new Array();
images[0]="image1.jpg"
images[1]="image2.jpg"
images[2]="image3.jpg"
images[3]="image4.jpg"
// start preloading
for(i=0; i<=3; i++)
imageObj.src=images[i];
</script>
其他无 JS 方法是将一些 html 放在页面中的某个位置,这样就不会被看到:
<image src="picture.jpg" border="0">
或 HTML...
<img src="images/arrow-down.png" class="hiddenPic" />
...和 CSS...
.hiddenPic
height:1px;
width:1px;
更多 JavaScript 方法:
function preload(images)
if (document.images)
var i = 0;
var imageArray = new Array();
imageArray = images.split(',');
var imageObj = new Image();
for(i=0; i<=imageArray.length-1; i++)
//document.write('<img src="' + imageArray[i] + '" />');// Write to page (uncomment to check images)
imageObj.src=images[i];
然后使用类似的方式加载图像:
<script type="text/javascript">
preload('image1.jpg,image2.jpg,image3.jpg');
</script>
【讨论】:
感谢所有建议!明天我会试一试,看看有什么效果。我确实尝试了 1x1 div 方法,但我正在使用的 rails 应用程序将缓存哈希分配给图像 url 的末尾......因此浏览器将它们视为与 css 中的图像不同的图像。【参考方案2】:"此解决方案似乎加载图像 进入dom两次...一次当js 加载它,然后当 div 加载它的层变成 可见...所以它进行了 2 个 http 调用, 因此不工作”
第二个 http 请求应该以 304 响应(未修改),所以我想这可以吗? 另一种选择是通过 jQuery 加载图像,然后通过 DOM 作为背景图像内联插入,例如:
jQuery.fn.insertPreload = function(src)
return this.each(function()
var $this = $(this);
$(new Image()).load(function(e)
$this.css('backgroundImage','url('+src+')');
).attr('src',src);
);
;
$('div').insertPreload('[huge image source]');
【讨论】:
【参考方案3】:像其他解决方案一样,硬编码 URL 建议对代码维护征税。避免这种情况并使用 jQuery 制定通用解决方案相对容易。
此函数选择所有隐藏元素,检查它们是否有背景图像,然后将它们加载到隐藏的虚拟元素中。
$(':hidden').each(function()
//checks for background-image tab
var backgroundImage = $(this).css("background-image");
if (backgroundImage != 'none')
var imgUrl = backgroundImage.replace(/"/g,"").replace(/url\(|\)$/ig, "");
$('<img/>')[0].src = imgUrl;
);
【讨论】:
请将第二个替换更改为:var imgUrl = backgroundImage.replace(/"/g,"").replace(/url\(|\)|"|'$/ig, "");
这是有效的 css background-image: url('....
例如注意单引号【参考方案4】:
CSS 预加载很容易。
示例:
body:after
display:none;
content: url(img01.png) url(img02.png) url(img03.png) url(img04.png)
【讨论】:
【参考方案5】:浏览器开始支持<link>
元素的rel="..."
属性的prefetch
和preload
属性。
Addy Osmani 的 post about the preload and prefetch properties 非常棒,并描述了何时应该使用它们:
预加载是向浏览器发送请求的早期获取指令 页面所需的资源(关键脚本、Web 字体、主图)。
预取服务的用例略有不同 — 未来导航 获取资源的用户(例如视图或页面之间)和 请求需要在导航中持续存在。如果页面 A 发起一个 对页面 B 所需的关键资源的预取请求, 关键资源和导航请求可以在 平行线。如果我们在这个用例中使用预加载,它将是 在页面 A 卸载时立即取消。
元素的使用方式如下:
<link rel="preload" as="image" href="https://your.url.com/yourimage.jpg" />
我正在设计一个包含多个步骤的表单,每个步骤都有不同的背景图像。当 Chrome 下载下一个背景图片时,此模式可解决步骤之间的“闪烁”问题。
【讨论】:
以上是关于预加载隐藏的 CSS 图像的主要内容,如果未能解决你的问题,请参考以下文章
JQuery - 预加载图像(使用 JQuery / 本机 JavaScript / CSS)
如何在 HTML 5 中为音频、视频、css、图像创建预加载器?