天天看點

QQ空間首頁背景圖檔淡出解析與不足完善

一件事情的發生總是有原因的,當然更多的是對技術本身的追求,一定要搞懂啦,廢話不多說,大寶劍直插主題。

  • 起因
  1. 以前做過一個xx項目,在登陸界面背景圖檔中,直接引用了一張大圖,css類似于這樣(background-image:url(a.jpg)),然後啪啪啪調試了一下,醜惡的面容出來,圖檔是從上往下一片一片的出來,互動和使用者體驗差到了極點,特别在網速不好的時候特别明顯。(不建議測試圖檔使用恐怖圖檔,效果你懂滴,嘿嘿嘿)
  2. 有一次突然的機會看到QQ空間背景圖檔,看到背景圖檔的顯示是那麼的優雅,那麼的淡然。心裡哭着想到,媽的終于找到解決的問題了,但是由于各種不可抗拒的原因一直推遲研究,知道這幾天才翻出來,把QQ空間源代碼摳出來研究了一番。

    效果圖比較:

    

QQ空間首頁背景圖檔淡出解析與不足完善
QQ空間首頁背景圖檔淡出解析與不足完善

      

具體大家可以自己設定個大圖做測試,和進QQ空間登陸首頁進行測試

  • 原理

佛說有因必有果,是以出現這個狀況肯定是有原因的。是以主要原因還是浏覽器的渲染問題,浏覽器是從上往下進行頁面渲染的,當你設定background-image的時候,浏覽器就解析這個屬性,然後去下載下傳這個圖檔。但是由于圖檔一般都不會太小,是以浏覽器不可能一次性将檔案請求過來,是以請求了多少渲染多少,是以就像拉窗簾式的一點點的下來,直到請求完了,全部渲染完成。通俗一點的例子就是浏覽器解析div和table的效果,div是有多少我渲染多少,但是table你必須全部加載完我再渲染

  • 研究過程

1.  首先去QQ空間首頁,使用chrome的Network工具監控所有請求的js檔案,發現不是很多的混淆後的js檔案和一個不斷重新整理二維碼的請求,這樣沒有找到有用的,值得看的東西(混淆的東西格式化了之後沒看出啥玩意,哈哈)。

QQ空間首頁背景圖檔淡出解析與不足完善

2. 但是俺不氣餒,然後在Element中檢查dom和style,開始發現好玩的東西了,空間中所使用的背景并不是使用background-image來實作的,它是一個div,然後檢查這個div的樣式,以及<img>标簽的樣式,然後我不斷調試這些樣式(就是一個一個的撤銷再加載),最後發現當我撤銷opacity: 1;樣式的時候,背景圖檔開始淡出了,然後再點又開始淡入,好了,發現重點了!!!

QQ空間首頁背景圖檔淡出解析與不足完善

3. 開始仔細關注着幾個标簽的樣式,發現罪魁禍首是css3的opacity和transition屬性。前端開發的應該不陌生,一個是透明度,一個是旋轉變換(....旋轉變換我閉着眼...媽的,都快唱起來了)。可以看效果

QQ空間首頁背景圖檔淡出解析與不足完善

4. 作為一個嚴謹,對自己代碼負責的工程師,我将QQ空間的首頁拿到不同浏覽器進行測試,最主要就是IE,因為其他浏覽器裝的話,預設都是最新版本,幾乎都支援CSS3的屬性了,隻有IE這個傻Ⅹ才會這麼多事,雖然IE6退出了市場,但是IE8-9還是有很多人用的,在IE下測,出現問題了,圖檔出現再也沒有那麼裝逼的淡出效果了,檢查了一下IE8中 渲染不出opacity和transition,IE9渲染不出transition,是以坑爹呀。至于圖檔不是一塊一塊加載,稍微查了下QQ空間在頁面中寫的js,使用的延遲加載。

  • 代碼實作
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body{
            margin: 0;
            padding: 0;
            border: 0;
        }
        .backgroundShow{
            position: absolute;
            left: 0;
            top: 0;
            z-index: -1;
            overflow: hidden;
            width: 100%;
            height:100%;
        }
        .backgroundImg{
            position: absolute;
            left: 0;
            top: 0;
            z-index: -2;
        }
        .showImg{
            opacity: 1;
        }

        .lay_background_img{
            transition: opacity 2s ease;
            opacity: 0;
        }
    </style>
</head>
<body>
    <div id="showImg" class="backgroundShow">
        <img id="ImgShow" class="lay_background_img backgroundImg">
    </div>
</body>
<script src="lib/test.js"></script>
<script>
    +function(){
        loadImage('http://z.k1982.com/show_img/201303/2013033012383895.jpg',imgLoaded);
    }();

    function loadImage(url, callback) {
        var img = new Image();
        img.src = url;
        img.onload = function(){ //圖檔下載下傳完畢時異步調用callback函數。
            callback.call(img); // 将callback函數this指針切換為img。
        };
    }

    function imgLoaded(){
        var img = document.getElementById("ImgShow");
        img.setAttribute("src",this.src);
        if(img.style.opacity!=undefined){
            img.style.opacity=1;
        }
    }
</script>
</html>
      

  廢話不說,代碼已貢獻出來。大家可以直接測試。但是,寫了這麼多js代碼,太煩了,這不是我開發的原則,我要偷懶,越少代碼越好。是以我想到插件啦,因為Jquery的普遍運用,我選擇了jquery插件,其實其他庫和原生插件也考慮的,但是已經寫了就先寫jquery插件啦。

  • 插件實作

對于插件,我們都要從嚴謹的角度出發,因為一個成熟的插件是要考慮和完善很多東西的,不能讓别人或者自己使用出現千奇百怪的問題,是以這個簡單的插件相容了IE8-9的淡出,而且抛出了一些配置,包括淡出動畫時間的問題呀,包括多個動畫随機顯示功能(屬于閑得蛋疼),其他功能大家有興趣可以自己随機拓展,直接上代碼

//延遲加載圖檔
        var imageT;
        var imgObjArr = new Array;
        if(options.isRandom){
            for(var i = 0;i<options.imgArr.length;i++){
                imageT = new Image();
                imageT.src = options.imgArr[i];
                imgObjArr.push(imageT);
            }
        }else {
            imageT = new Image();
            imageT.src = options.imgArr[0];
            imgObjArr.push(imageT);
        }

        //動态顯示
        imageT.onload =function(){
            console.log(options.isRandom)
            if(options.isRandom){
                var result =Math.round(Math.random() * (options.imgArr.length - 1));
                $("#ImgShow").attr("src",options.imgArr[result]);
            }else{
                $("#ImgShow").attr("src",options.imgArr[0]);
            }

            //對于統一不支援css3屬性的用jquery的fadeIn解決淡出問題
            if($("body")[0].style.opacity==undefined || $("body")[0].style.transition==undefined){
                $("#divShow").fadeIn(options.imgSecond);
            }else{
                $("#ImgShow").css({"opacity":"1"});
            }
           };
      

  隻是一些,不貼太多了,篇幅太長,可以到github上來下載下傳,記得加顆星哦,關注哦,麼麼哒~~~~

github位址:  https://github.com/GerryIsWarrior/setBackgroundImage_js

繼續閱讀