我有几个带背景图片的div。我想知道如何使用gif图像预加载那些背景图像,因为一些背景图像非常大。执行以下操作无效:
HTML:
<div id="glykopeels" onload="loadImage()">Glykopeels Content</div>
<div id="facials" onload="loadImage2()">Facials Content</div>
CSS:
#glykopeels{
background: #ebebeb url(http://lamininbeauty.co.za/images/products/preloader.gif) no-repeat top right;
background-size: contain;
}
#facials{
background: #ebebeb url(http://lamininbeauty.co.za/images/products/preloader.gif) no-repeat top right;
background-size: contain;
}
JS:
function loadImage(){
document.getElementById('glykopeels').style.background = '#ebebeb url(http://lamininbeauty.co.za/images/products/glykopeel.jpg);';
}
function loadImage2(){
document.getElementById('facials').style.background = '#ebebeb url(http://lamininbeauty.co.za/images/products/facial.jpg);';
}
我想在onload函数中定义该元素的不同ID,并为该新ID定义css是另一种可能性吗?因此只更改onload函数中该元素的id?
谢谢
答案 0 :(得分:5)
首先: div没有onload属性。 编辑:请阅读以下评论,非常有趣!
其次,你应该在引号之间放置url(如果需要,可以转义它们):url('http://lamininbeauty.co.za/images/products/facial.jpg')
第三,没有名为preloader.gif
的图片,但是有一张名为loader.gif
的图片,所以我使用了那张图片来修复&#39;你的css部分是我在底部的jsfiddle演示链接中的解决方案。
在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'); };
在您的身体中:添加属性&#39; data-bg_img&#39; (根据html5约定,以数据开头 - )到你想要使用这种技术的元素,并让它包含你的背景网址,如下所示:
<div id="glykopeels" data-bg_img="http://lamininbeauty.co.za/images/products/glykopeel.jpg">Glykopeels Content</div>
&#39;可选&#39;在你的身体初始化:
<!--
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');">
<强>手动/解释:强>
图像有一个onload-event,所以我们在html(底部)放置一个加载图像,它会触发它自己的onload-event,一旦浏览器实际上就调用repBg()
下载了这个loading-image!
函数repBg()
最多需要2个参数:
调用后,函数repBg()
将在主体中搜索符合第二个参数或*
的elementTagNames,然后使用第一个参数对其进行过滤。
对于保留在过滤的htmlObjectCollection中的每个htmlObject,创建一个新图像(不附加到正文),其中htmlObject的属性值(url)对应于函数的第一个参数作为图像源,与htmlObjectCollection一起引用id(属性data-id
)以供参考
一旦这些图像加载,它们就会触发onload事件:调用repBg
的{{1}}方法,用新的(大)背景图像替换引用的htmlObject的背景(和你的其余部分)。为了进一步模块化,您可以扩展该功能。
最后,注意:背景图片加载,以便它们出现在源代码中,也就是您希望工作的方式!
您可以在this fiddle: http://jsfiddle.net/epdDa/
中看到它的实际效果 更新版本2:非常棒的回归!!和COPY-PASTE NOBRAIN解决方案
我的生活日光让我感到恼火,因为我的第一个解决方案没有提供优雅的后备。所以我提出了一个不同的解决方案,提供优雅的后备
还在 IE6 和FF12中进行了全面测试
它的工作原理如下:
在你的身体:简单设置你的div的课程,以预先加载&#39;并将它的style-attribute设置为它应该正常加载的backgroundimage。像这样:
exec
这很容易吗? 然后将以下脚本放在HTML的HEAD(这很重要)中:
<div id="facials" class="preload" style="background: #ebebeb url('http://lamininbeauty.co.za/images/products/facial.jpg') no-repeat top right;">Facials Content</div>
<强>解释强>
它花了我一整夜..但我找到了办法
如果启用了javascript,函数repBg将通过向文档头(它所在的位置,注意将它放在最后一个css脚本之后)写一个额外的样式块来开始,它为所有元素设置loader-background-image上课&#39; preload&#39; (从而在页面加载时显示加载图像)
如果加载了加载图像的加载测试图像并加载了窗口(以获取正文中的所有元素),那么它与版本1基本相同。只是这次我们从中获取并匹配来自的URL元素的样式 - 属性和onload随后清空元素的样式属性。
由于此功能自动执行并使用类似于版本1的版本(如上所述)覆盖自身,因此您只需在功能的最后一行调整参数&#39; repBg&#39;。
请注意:在其初始状态// 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');
中最多接受4个参数:className,Url,cssPrepend和cssAppend。
要查看它的实际效果(请勿忘记按照说明清理浏览器缓冲区),
点击this fiddle: http://jsfiddle.net/epdDa/1/
无论谁使用此功能,如果你相信我,我将不胜感激!
<强>更新强>
额外的解释和评论的答案。
两个版本之间的主要区别
从技术上讲,两个版本都使用几乎相同的技术,因此没有真正的区别。
为什么我选择使用内联css?为什么必须&#39;你使用内联css来实现这个目的吗?
首先,我花了小时来避免内联css。 (我没有松开它们,我学会了不起作用的方式,同样有用)。接下来,我想再次指出所有当前的答案,包括你要去的方向,将实际的背景图像url与css分开,而在css中,你分别在每个div上设置加载器图像,更有意义。版本2只使用可配置的类名。
文档“HEAD”中的reading和writing个css块都是一团糟...... 我是否提到了链接的外部css文件.. ??
在我看来,所有这些都需要这么多额外的代码和cpu-cycles以及在每个页面加载上阻塞/暂停浏览器,以便核心原则工作:最后一个有效的css规则适用。因此,加载图像会尽快显示,因为它是页面加载时指定的背景图像,正是人们想要的这种功能。如果元素不再是“预加载”的一部分。类?右:它的内联css生效,更新速度与浏览器可以渲染一样快(如果图像已经加载)。好的。
因此,如果您通过简单地使用repBg
来牺牲(真实)xhtml支持,那么目前仍然证明这是最好的&#39;要走的路(你可以在之前的2个链接中阅读)。它仍然适用于外部链接的CSS。我的第三次(KISS-)投票支持第2版。
我对第2版的第四次投票是因为:document.write
函数已准备好让它repBg
方法(=函数)&#39;已升级&#39;所以你只能拿出预载&#39;来自班级的价值&#39;值列表。一个简单的replace()就足够了(目前没有速度)。
我对第2版的第五次也是最后一次投票是因为它优雅的后备设置,修复或阻止某些浏览器使用额外的“spice”也相对容易。
最后,关于速度:我认为版本2总是让人感觉更快:onload-image的显示速度几乎与浏览器可以获取它一样快(好像这个额外的css总是在那里开始),加载动画加载snappy因为:他们的负载已经在头部启动,并且浏览器不会下载被覆盖的图像,直到该函数调用。此外,他们看起来互动而不会分心。但..当加载实际背景图像和css更新时:bam!图像在那里,没有从上到下扫描的效果&#39;。这种效果让人觉得很难受。实际上,我已经说服了,并且会对图片中的图像进行调整,以获得快照和增加感知的初始页面加载量。注意,这是我的观点。你的里程可能会有所不同哈哈。
祝你好运! (如果你喜欢/使用这个想法/功能请投票,谢谢!)答案 1 :(得分:2)
1)div
元素没有load
个事件,此事件仅适用于正文,图片和脚本标记。
编辑:像@icktoofay所指出的那样,在HTML规范中,所有元素都存在onload
,但主流浏览器尚未支持此功能。
2)将此脚本标记放在html页面的末尾:
<script>
function loadImages() {
var glykopeels = document.getElementById('glykopeels');
var facials = document.getElementById('facials');
glykopeels.style.backgroundImage = 'url(http://lamininbeauty.co.za/images/products/glykopeel.jpg)';
facials.style.backgroundImage = 'url(http://lamininbeauty.co.za/images/products/facial.jpg)';
3)你可以像你一样设置style.background
,但不要将;
放在字符串的末尾,否则它将无效。
小提琴:http://jsfiddle.net/pjyH9/
修改强>
似乎加载程序图像没有显示,因为一旦浏览器收到新图像的第一个字节,它就会从后台删除loader.gif。我们采取另一种方法。 这是一个将图像加载到缓存的函数,然后 - 当加载图像时 - 将图像设置为具有指定id的元素的背景。
function loadImageToBackground(elementId, imageUri) {
var img = new Image();
img.onload = function() {
document.getElementById(elementId).style.backgroundImage = "url('" + imageUri + "')";
};
img.src = imageUri;
}
您想要加载器的元素:
// past the element id and the image url to the function
loadImageToBackground('glykopeels', 'http://image....');
我很确定这会奏效。函数loadImageToBackground
执行基本工作,如果需要,可以扩展和添加更多功能。
这里有一个工作示例:http://jsfiddle.net/pjyH9/19/ (它加载2个图像,每个1.5mb,因此您可以看到加载器正在运行)。
答案 2 :(得分:1)
我认为你要做的是让背景图像在加载后切换到大的JPG图像。你应该能够适应这样的事情为你工作:
<html>
<head>
<title>Image Load Test</title>
<script type="text/javascript">
function loadImage(preloader, imageDiv) {
document.getElementById(imageDiv).style.background = '#ebebeb url('+preloader.src+') no-repeat top right';
// I think resetting the background property also resets backgroundSize.
// If you still want it 'contained' then you need to set the property again.
document.getElementById(imageDiv).style.backgroundSize = 'contain';
}
</script>
<style type="text/css">
#testImage {
background: #ebebeb url(small-image.gif) no-repeat top right;
background-size: contain;
}
#preloads { display: none; }
</style>
</head>
<body>
<div id="testImage">Some Content</div>
<div id="preloads">
<img src="full-image.jpg" onload="loadImage(this, 'testImage')">
</div>
</body>
</html>
这里的主要区别在于我正在<img>
中预加载JPG图像,该<div>
隐藏在display: none
onLoad
属性中以隐藏它。我不确定div
事件究竟对onLoad
做了什么,但我很确定这不是你想要的。将img
事件放在background-size
元素中会导致事件在图像完全加载后触发,我相信 你想要的。
编辑 我在JavaScript中添加了一行来重置{{1}}属性。如果那不是你想要的,那就忽略那个部分。