首先: div 没有 onload 属性。编辑:请阅读下面的评论,非常有趣!
其次,您应该将 url 放在引号之间(如果需要,将它们转义):url('http://lamininbeauty.co.za/images/products/facial.jpg')
第三,没有名为 的图像preloader.gif
,但有一个名为 的图像loader.gif
,因此我使用该图像在底部的 jsfiddle 演示链接中为我的解决方案“修复”您的 css 部分。
在 SO 的服务器迁移期间,我为您编写了一个简单的自定义函数,它完全符合您的要求。
在IE6和 FF12 中测试。
要对此进行测试:请清除您的浏览器缓冲区,否则您将看不到它的实际效果(它会运行得太快),因为图像可能会在第二个视图上被缓冲(再次,非常适合您的目标)!
JavaScript:
var repBg=function(a, t){ t=t||'*'; // by GitaarLAB
var c=document.getElementsByTagName(t), i=c.length, r=[];
while(i--){if (c[i].getAttribute(a)){r.push(c[i]);}} c=r; i=c.length;
repBg.exec=function(){
c[this['data-i']].style.background="#ebebeb url('"+this.src+"') no-repeat top right";
};
while(i--){ if (c[i].getAttribute(a)) {
r=new Image();
r.onload=repBg.exec;
r['data-i']=i;
r.src=c[i].getAttribute(a);
}}
};
// one could run repBg onload, but better to run it when the image has actually loaded, see html!
// window.onload=function(){ repBg('data-bg_img','div'); };
在您的 BODY 中:将属性“data-bg_img”(根据 html5 约定,以 data- 开头)添加到您要使用此技术的元素中,并使其包含您的背景 url,如下所示:
<div id="glykopeels" data-bg_img="http://lamininbeauty.co.za/images/products/glykopeel.jpg">Glykopeels Content</div>
身体中的“可选”初始化:
<!--
trigger the replace background function when the loader image has actually loaded!
rewriting the onload with nothing to prevent infinite loop in IE6 (and greater?) !!
-->
<img src="http://lamininbeauty.co.za/images/products/loader.gif" style="display:none;" onload="this.onload=null; repBg('data-bg_img','div');">
手动/说明:
图像确实有一个加载事件,所以我们在 html 中放置一个加载图像(在底部),这将触发它自己的加载事件,repBg()
一旦浏览器实际下载了这个加载图像就会调用!!!
该函数repBg()
最多需要 2 个参数:
- 包含应选择的属性的第一个强制字符串,
- 第二个可选参数可以定义标记名(以限制第一个参数)。
当被调用时,函数repBg()
将在主体中搜索符合第二个参数的 elementTagNames,或者*
然后使用第一个参数过滤它们。
对于保留在过滤后的 htmlObjectCollection 中的每个 htmlObject,将创建一个新图像(不附加到正文),其中 htmlObject 的属性值 (url) 对应于函数的第一个参数作为图像源,以及 htmlObjectCollection 的引用 id (attribute data-id
) 以供参考。
一旦这些图像加载,它们就会触发它们的 onload 事件:调用repBg
的exec
方法,用新加载的(大)背景图像(以及你的 css 的其余部分)替换引用的 htmlObject 的背景。为了进一步模块化,您可以扩展该功能。
最后,请注意:背景图像按照它们出现在源代码中的顺序加载,也就是您期望的工作方式!
你可以在这个小提琴中看到它的作用:http://jsfiddle.net/epdDa/
更新版本 2:优雅的回退!和复制粘贴 NOBRAIN 解决方案
我的第一个解决方案没有提供优雅的回退,这让我很生气。所以我做了一个不同的解决方案来提供优雅的回退。在IE6
和 FF12
中也经过全面测试它的工作原理如下:
在您的 BODY 中:简单地将您的 div 的类设置为“预加载”并将其样式属性设置为它应该正常加载的背景图像。像这样:
<div id="facials" class="preload" style="background: #ebebeb url('http://lamininbeauty.co.za/images/products/facial.jpg') no-repeat top right;">Facials Content</div>
那很容易吧?
然后将以下脚本放在 HTML 的 HEAD(这很重要)中:
// getElementsByClass original by dustin diaz, modified by GitaarLAB
document.getElementsByClassName=document.getElementsByClassName||function(searchClass,node,tag) {
var classElements = [], i=0, j=0;
if (!node){node = document;}
if (!tag){tag = '*';}
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp('(^|\\\\s)'+searchClass+'(\\\\s|$)');
for (; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i]; j++;}
} return classElements;
};
var repBg=(function(n,u,p,a,i,r){ // by GitaarLAB
window.onload=function(){repBg(1);};
i=new Image(); i.onload=function(){this.onload=null; repBg(2);};
document.write("<style>."+n+"{background:"+p+" url("+u+") "+a+
" !important; background-size: contain !important;}"+
"</style>");
i.src=u; r=0;
return function(t){
r=r+t; if(r>2){
var c=document.getElementsByClassName(n), i=0, l=c.length, s;
repBg.exec=function(){
document.getElementById(this['data-id']).className='';
};
for(;i<l;i++){
r=new Image();
r.onload=repBg.exec;
r['data-id']=c[i].getAttribute('id');
s=c[i].getAttribute('style');
try { // sane browsers
r.src=s.match(/url\('?([^'"]*)'?\)/i)[1];
} catch(e) { // <IE8
r.src=s.cssText.match(/url\('?([^'"]*)'?\)/i)[1];
}
}
}
};
})('preload','http://lamininbeauty.co.za/images/products/loader.gif','#ebebeb','no-repeat top right');
说明:
我花了一整夜……但我找到了办法。
如果启用了 javascript,函数 repBg 将首先向文档头部写入一个额外的样式块(它所在的位置,注意将其放在最后一个 css 脚本之后),为所有元素设置 loader-background-image类“预加载”(从而在页面加载时显示加载图像)。
如果加载了加载图像的加载测试图像并且加载了窗口(以获取正文中的所有元素),那么它与版本 1 基本相同。只是这次我们从元素的样式属性和 onload 随后清空元素的样式属性。
由于此函数会自动执行并用类似于版本 1 的版本(如上)覆盖自身,因此您可以简单地在函数“repBg”的最后一行调整参数。
请注意:在初始状态repBg
下,最多接受 4 个参数:className、Url、cssPrepend 和 cssAppend。
要查看它的实际效果(不要忘记按照说明清理浏览器缓冲区),
请单击此小提琴:http://jsfiddle.net/epdDa/1/
谁使用此功能,如果您感谢我,我将不胜感激!
更新:
评论的额外解释和答案。
两个版本之间的主要区别 从
技术上讲,两个版本使用几乎相同的技术,因此没有真正的区别。
- 对于版本 1,javascript 是使页面工作所需的粘合剂,但可以在有效的真正 xhtml 和纯 html 中工作。
但是,关闭 javascript 的人将获得一个无法正常工作的站点(仅显示加载 gif)。请注意,所有其他当前答案,包括您要去的方向,都会遇到这个问题!
- 在版本 2 中,javascript 只是增强页面交互(网站应编码的方式)的香料,但仅适用于 html(或无效的 xhtml)。
但是,这应该确保关闭 javascript 的人仍然可以看到正常运行的页面。IE: 不需要 javascript来正确显示网站。这个概念被称为“优雅的后备”或“优雅地降级”。我对版本 2 投了第 1 票。
额外奖励:这条路径为您提供了普通的验证和语义 html,因为您使用了古老的可信赖的内联样式、id 和类。我对第 2 版的第 2 票
为什么我选择使用 in-line css?为什么“必须”使用内联 CSS 才能正常工作?
首先,我花了几个小时来避免使用内联 CSS。(我没有松开它们,我学到了不起作用的方法,但同样有用)。接下来,我想再次指出,所有当前的答案,包括你要去的方向,实际的背景图像 url 与 css 分开,而在 css 中,你分别在每个 div 上设置加载器图像,一个类会更有意义。版本 2 仅使用可配置的类名。
在文档的 HEAD 中读取和写入css 块都是一团糟。
我是否提到了链接的外部 css 文件..??
在我看来,所有这些都需要大量额外的代码和 cpu 周期,并在每次页面加载时阻止/停止浏览器,以便核心原则起作用:最后一个有效的 css 规则适用。因此加载图像会尽快显示,因为它是页面加载时指定的背景图像,这正是人们想要从这样的功能中获得的。如果元素不再是“预加载”类的一部分?对:它的内联 css 生效,以浏览器可以渲染的速度更新(如果图像已经加载)。好的。
因此,如果您通过简单地使用来牺牲(真正的)xhtml 支持document.write
,那么目前仍然证明这种方式是“最好的”方式(正如您可以在前面的 2 个链接中阅读的那样)。并且它仍然可以与外部链接的 css 一起使用。我对第 2 版的第三次(KISS-)投票。
我对版本 2 的第四次投票是因为:该repBg
函数已准备好将其exec
方法(=函数)“升级”,因此您只能从类的 valuelist 中取出“preload”值。一个简单的 replace() 就足够了(目前为了速度而忽略了)。
我对版本 2 的第五次也是最后一次投票是,由于它是优雅的后备设置,因此修复或阻止某些浏览器使用额外的“香料”也相对容易。
最后,至于速度:我认为版本 2 总是会感觉更快捷:onload-image 的显示速度几乎与浏览器获取它的速度一样快(好像这个额外的 css 总是在那里一样),加载动画加载速度很快,因为:它们的加载已经在头部启动,浏览器在函数调用之前不会下载被否决的图像。此外,它们看起来互动而不会分心。但是..当实际的背景图像被加载并且css更新时:bam!图像在那里,没有从上到下的扫描“效果”。这种效果感觉该死的快。实际上,我确信并将对相册中的图像进行改编,以适应快速感觉和增加感知的初始页面加载。请注意,这是我的观点。你的里程可能会有所不同哈哈。
祝你好运!!(如果你喜欢/使用这个想法/功能,请投票,谢谢!!)