使用临时gif图像预加载背景图像

Dex*_*ave 5 javascript

我有几个背景图像的div.我想知道如何使用gif图像预加载那些背景图像,因为一些背景图像非常大.执行以下操作不起作用:

HTML:

<div id="glykopeels" onload="loadImage()">Glykopeels Content</div>
<div id="facials" onload="loadImage2()">Facials Content</div>
Run Code Online (Sandbox Code Playgroud)

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;
    }
Run Code Online (Sandbox Code Playgroud)

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);';
    }
Run Code Online (Sandbox Code Playgroud)

我想在onload函数中为该元素定义一个不同的ID,并为该新ID定义css是另一种可能性吗?这样只更改onload函数中该元素的id?

谢谢

Git*_*LAB 5

第一: div没有onload属性.编辑:请阅读下面的评论,非常有趣!

其次,您应该将url放在引号之间(如果需要,可以转义它们):url('http://lamininbeauty.co.za/images/products/facial.jpg')

第三,没有调用图像preloader.gif,但是有一个图像被调用loader.gif,所以我使用那个来修复你的css部分,以便在底部的jsfiddle demo链接中找到我的解决方案.

在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');  };
Run Code Online (Sandbox Code Playgroud)

在你的BODY中:将属性'data-bg_img'(按照html5约定,以数据开头)添加到你想要使用这种技术的元素,并让它包含你的背景网址,如下所示:

<div id="glykopeels" data-bg_img="http://lamininbeauty.co.za/images/products/glykopeel.jpg">Glykopeels Content</div>
Run Code Online (Sandbox Code Playgroud)

您身体中的"可选"初始化:

<!--
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');">
Run Code Online (Sandbox Code Playgroud)

手册/说明:
图像DO有一个onload-event,所以我们在html(底部)放置一个加载图像,它将触发它自己的onload-event,repBg()一旦浏览器实际下载了这个加载图像就调用!

该函数repBg()最多需要2个参数:

  • 第一个包含应该选择的属性的必填字符串,
  • 第二个可选参数可以定义标记名(限制第一个参数).

调用时,函数repBg()将在主体中搜索符合第二个参数的elementTagNames,*然后使用第一个参数过滤它们.
对于保留在已过滤的htmlObjectCollection中的每个htmlObject,将创建一个新图像(不附加到正文),其中htmlObject的属性值(url)对应于函数的第一个参数作为image-source,以及htmlObjectCollection的引用id(属性)data-id) 以供参考.
一旦这些图像加载,它们就会触发它们的onload事件:调用repBgexec方法用新的新加载的(大)背景图像(以及你的css的其余部分)替换引用的htmlObject的背景.为了进一步模块化,您可以扩展该功能.

最后,请注意:背景图像按照它们出现在源中的顺序加载,也就是您期望事物工作的方式!

你可以在这个小提琴中看到它的运作:http://jsfiddle.net/epdDa/


更新版本2:非常棒的回归!和COPY-PASTE NOBRAIN解决方案
它使我的生活日光惹恼了我的第一个解决方案没有提供优雅的后备.所以我提出了一个不同的解决方案,提供优雅的后备.
IE6和FF12中也经过了全面测试它的工作方式如下:
在你的BODY:SIMPLY中将你的div类设置为'preload'并将它的style-attribute设置为它应该正常加载的backgroundimage.像这样:

<div id="facials" class="preload" style="background: #ebebeb url('http://lamininbeauty.co.za/images/products/facial.jpg') no-repeat top right;">Facials Content</div>
Run Code Online (Sandbox Code Playgroud)

这很容易吗?
然后将以下脚本放在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');
Run Code Online (Sandbox Code Playgroud)

说明:
整晚都花了我..但我找到了办法.
如果启用了javascript,函数repBg将通过向文档头(它所在的位置,注意将它放在最后一个css脚本之后)写一个额外的样式块来开始,它为所有元素设置loader-background-image class'preload'(从而在pageload处显示load-image).
如果加载了加载图像的加载测试图像并加载了窗口(以获取正文中的所有元素),那么它与版本1基本相同.只是这次我们从中获取并匹配来自的URL元素的style-atribute和onload随后清空元素的style-attribute.

由于此函数自动执行并使用类似于版本1的版本(如上所述)覆盖自身,因此您只需在函数'repBg'的最后一行调整参数即可.
请注意:在它的初始状态中repBg最多接受4个参数:className,Url,cssPrepend和cssAppend.

要查看它的运行情况(不要忘记按照说明清理浏览器缓冲区),
请单击此小提琴:http://jsfiddle.net/epdDa/1/

无论谁使用这个功能,如果你相信我,我将不胜感激!


更新:
评论的额外解释和答案.


两个版本之间的主要区别从技术上讲,两个版本使用几乎相同的技术,因此没有真正的区别.

  • 对于版本1,javascript是使页面工作所需的粘合剂,但是在有效的真实xhtml和普通html中工作.
    但是,关闭javascript的人将获得一个非功能性站点(仅显示loading-Gif).请注意,所有其他当前答案,包括您前往的方向,都会遇到此问题!
  • 对于版本2,javascript只是增强页面交互的方式(网站应该编码的方式),但仅适用于html(或无效的xhtml).
    但是,这应该确保关闭javascript的人仍然看到正常运行的页面.IE:javascript 不需要正确显示网站.这个概念被称为"优雅的后备"或"优雅地退化".我对第2版的投票没有.
    额外的奖励:这条路径为您提供普通的香草验证和SEMANTIC HTML,因为您使用古老的可信赖的在线风格,id和类.我对第2版的投票没有2

为什么我选择使用内联css?为什么'必须'你使用内联css才能工作?
首先,我花了几个小时来避免内联css.(我没有松开它们,我学会了不起作用的方式,同样有用).接下来,我想再次指出所有当前的答案,包括你要去的方向,将实际的背景图像url与css分开,而在css中,你分别在每个div上设置加载器图像,更有意义.版本2只使用可配置的类名.

无论阅读写作在文档的HEAD CSS块是那种乱七八糟的..
我提到链接的外部CSS文件..?

在我看来,所有这些都需要这么多额外的代码和cpu-cycles并阻塞/暂停每个页面加载的浏览器,以便核心原则工作:最后一个有效的css规则适用.因此,加载图像会尽快显示,因为它是页面加载时指定的背景图像,正是人们想要的这种功能.如果元素不再是'preload'类的一部分?右:它的内联css生效,更新速度与浏览器可以渲染一样快(如果图像已经加载).尼斯.

因此,如果你通过简单的使用牺牲(真实)xhtml支持document.write,它目前仍然是这种方式是"最好的"方式(你可以阅读前面的2个链接).它仍然适用于外部链接的CSS.我的第三次(KISS-)投票支持第2版.

我对第2版的第四次投票是因为:该repBg函数准备让它的exec方法(=函数)'升级',所以你只能从类'valuelist中取出'preload'值.一个简单的replace()就足够了(目前还没有速度).

我对第2版的第五次也是最后一次投票是因为它优雅的后备设置,它也相对容易修复或阻止某些浏览器使用额外的'spice'.

最后,至于速度:我认为版本2总是会感觉更快:onload-image的显示速度几乎与浏览器可以获取它一样快(好像这个额外的css总是在那里开始),加载动画加载snappy,因为:他们的负载已经在头部启动,浏览器将不会下载被否决的图像,直到该功能要求.此外,他们看起来互动而不会分心.但..当加载实际背景图像和css更新时:bam!图像在那里,没有从上到下扫描'效果'.这种效果让人觉得很难受.实际上我已经说服了,并且会对galary中的图像进行调整,以获得快照和增加感知的初始页面加载量.注意,这是我的观点.你的里程可能会有所不同哈哈.

祝好运!!(如果你喜欢/使用这个想法/功能请投票,谢谢!!)