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


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

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

    效果圖比較

    

      

 

 

 

 

 

 

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

 

  • 原理

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

 

  • 研究過程

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

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

 

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

 

 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM