js 懶加載圖片 demo

html + js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        body, div, img {
            margin: 0;
            padding: 0
        }
    </style>
</head>
<body>

<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/001.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/002.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/003.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/004.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/005.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/006.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/007.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/008.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/009.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/010.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/011.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/012.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/013.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/014.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/015.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/016.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/017.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/018.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/019.jpeg" alt="范冰冰"/><br/>
<img src="images/default.jpg" realSrc="http://localhost:63342/tql/2/images/020.jpeg" alt="范冰冰"/><br/>
</body>
</html>

<script type="text/javascript" src="js/utils.js"></script>
<script type="text/javascript">
    var oImgs = document.getElementsByTagName("img");
    for (var i = 0; i < oImgs.length; i++) {
        var oImg = oImgs.item(i);
        oImg.posi = utils.getOffset(oImg).top + utils.getEleClientWidthAndHeightContainBorder(oImg).height;
    }

    window.onscroll = function () {
        var oImgs = document.getElementsByTagName("img");
        for (var i = 0; i < oImgs.length; i++) {
            var oImg = oImgs.item(i);
            //瀏覽器的底邊距離body的高度 = 獲取滾動條相對於文檔頂部的偏移 + 文檔可視區域高度
            // browserBottom     =    document.documentElement.scrollTop(獲取滾動條相對於文檔頂部的偏移)     +      document.documentElement.clientHeight(文檔可視區域高度)
            var browserBottom = (document.documentElement.scrollTop || document.body.scrollTop) + (document.documentElement.clientHeight || document.body.clientHeight);

            loadImg(oImg, browserBottom);
        }
    }

    function loadImg(oImg, browserBottom) {
        if (oImg.loaded) {
            return;
        }
        if (oImg.posi < browserBottom) {
            var tempImg = new Image();
            var src = oImg.getAttribute("realSrc");
            src = src + "?" + Math.random();
            tempImg.src = src;
            oImg.src = "images/loading.gif";
            tempImg.onload = function () {
                oImg.src = src;
                oImg.loaded = true;
            }
        }
    }
</script>


依賴 utils.js

/*工具包,單例模式*/

var utils = {
    /*
     listToArray:將類數組轉化成數組,兼容所有瀏覽器
     參數:listArray:類數組
     用法:var ary = utils.listToArray(lis);
     */
    listToArray: function (listArray) {
        var ary = [];
        try {
            // 通過call方法改變slice中this的指向,克隆出類數組中的元素
            ary = Array.prototype.slice.call(listArray, 0);
        }
        catch (e) {
            //ie下...
            // 循環把類數組中的元素放到數組中
            for (var i = 0; i < listArray.length; i++) {
                ary[ary.length] = listArray[i];
            }
        }
        return ary;
    },
    /*
     toJSON:把JSON格式字符串轉換成JSON對象
     參數:str JSON格式字符
     用法:var obj = utils.toJSON(str);
     * */
    toJSON: function (str) {
        /*if ("JSON" in window) {
         return JSON.parse(str);
         } else {
         //ie 6 7
         return eval("(" + str + ")");
         }*/
        return "JSON" in window ? JSON.parse(str) : eval("(" + str + ")");
    },
    /*
     toJSONString:Json對象轉字符串方法
     參數:obj JSON對象
     用法:var str = utils.toJSONString(obj);
    * */
    toJSONString: function (obj) {
        var S = [];
        for (var item in obj) {
            obj[item] = typeof obj[item] == 'string' ? '"' + obj[item] + '"' : (typeof obj[item] == 'object' ? this.toJSONString(obj[item]) : obj[item]);
            S.push(item + ':' + obj[item]);
        }
        return '{' + S.join(',') + '}';
    },
    /*
     * avgFn1:輸入一組數字求平均數,保留2位小數
     * 參數:10, 10, 9, 8, 1...
     * 用法:var avg = utils.avgFn1(10, 10, 9, 8, 1)
     */
    avgFn1: function () {
        //1.把arguments 類數組轉換成數組
        var ary = [];
        for (var i = 0; i < arguments.length; i++) {
            ary[ary.length] = arguments[i];
        }
        //2.給數組進行排序,然後去掉首尾
        ary.sort(function (a, b) {
            return a - b;
        })

        ary.shift(); //去首
        ary.pop(); //去尾

        //3.求和求平均
        var total = null;
        for (var i = 0; i < ary.length; i++) {
            total += ary[i];
        }

        return (total / ary.length).toFixed(2);

    },
    /* 優化
     * avgFn2:輸入一組數字求平均數,保留2位小數
     * 參數:10, 10, 9, 8, 1...
     * 用法:var avg = utils.avgFn2(10, 10, 9, 8, 1)
     */
    avgFn2: function () {
        //1.把arguments 類數組轉換成數組(用類數組轉換成數組的優化)
        /*var ary = [];
         for (var i = 0; i < arguments.length; i++) {
         ary[ary.length] = arguments[i];
         }*/
        var ary = Array.prototype.slice.call(arguments, 0);

        //2.給數組進行排序,然後去掉首尾
        ary.sort(function (a, b) {
            return a - b;
        }).shift(); //去首
        ary.length--; //去尾

        //3.求和求平均 優化
        return (eval(ary.join("+")) / ary.length).toFixed(2);
    },
    /* 優化
     * avgFn3:輸入一組數字求平均數,保留2位小數
     * 參數:10, 10, 9, 8, 1...
     * 用法:var avg = utils.avgFn3(10, 10, 9, 8, 1)
     */
    avgFn3: function () {
        //1.把arguments 類數組轉換成數組(用類數組轉換成數組的優化)
        /*var ary = [];
         for (var i = 0; i < arguments.length; i++) {
         ary[ary.length] = arguments[i];
         }*/
        var ary = Array.prototype.slice.apply(arguments, [0]);

        //2.給數組進行排序,然後去掉首尾
        ary.sort(function (a, b) {
            return a - b;
        }).shift(); //去首
        ary.length--; //去尾

        //3.求和求平均 優化
        return (eval(ary.join("+")) / ary.length).toFixed(2);
    },
    /* 深度優化
     * avgFn4:輸入一組數字求平均數,保留2位小數
     * 參數:10, 10, 9, 8, 1...
     * 用法:var avg = utils.avgFn4(10, 10, 9, 8, 1)
     */
    avgFn4: function () {
        //類數組轉成數組,在給數組進行排序
        [].sort.call(arguments, function (a, b) {
            return a - b;
        });
        [].shift.call(arguments); //去首
        [].pop.call(arguments); //去尾
        //求和求平均 優化
        //console.info(arguments.length)
        return (eval([].join.call(arguments, "+")) / arguments.length).toFixed(2);
    },
    /*
     * regExec:正則捕獲符合規則的所有結果,原理利用改變正則的懶惰性
     * 參數:reg:正則表達式/g str 要捕獲結果的字符串
     * 用法:var ary = utils.regExec(reg,str)
     */
    regExec: function (reg, str) {
        var ary = [];
        var res = reg.exec(str);
        while (res) {
            ary.push(res.shift());
            res = reg.exec(str);
        }
        return ary;
    },
    /*
     * strMatch:字符串捕獲符合正則規則的所有結果
     * 侷限:當reg存在分組的情況下,str.match(reg)就無法處理了
     * 參數:reg:正則表達式/g str 要捕獲結果的字符串
     * 用法:var ary = utils.strMatch(reg,str)
     */
    strMatch: function (reg, str) {
        var ary = str.match(reg);
        return ary;
    },
    /*
     * getCss:獲取某個元素的某個具體css結果
     * 參數:ele:元素 attr css屬性名稱
     * 用法:var obj = utils.getCss(ele,attr)
     */
    getCss: function (ele, attr) {
        if (typeof getComputedStyle == "function") {
            return getComputedStyle(ele, null)[attr];
        } else {
            //ie 6 7 8
            return ele.currentStyle[attr];
        }
    },
    /*
     獲取任意元素距離body的偏移,相對與document的偏移量
     通過向上迭代offsetParent,可以計算出相對於document的偏移量,也就是相對與頁面的偏移量。
     此方法的問題:
     1)對於使用表格和內嵌框架佈局的頁面,由於不同瀏覽器實現元素方式的差異,得到的結果就不精確了。
     2)每次都需要一級一級向上查找offsetParent,效率太低。
     */
    getOffsetSum: function (ele) {
        var top = 0, left = 0;
        while (ele) {
            if (window.navigator.userAgent.indexOf("MSIE 8") > -1) {
                top += ele.offsetTop;
                left += ele.offsetLeft;
            } else {
                //在標準瀏染器下要加上邊框
                top += ele.offsetTop + ele.clientTop;    //ele.clientTop 是上邊框的寬
                left += ele.offsetLeft + ele.clientLeft; //ele.clientLeft 是左邊框的寬
            }
            ele = ele.offsetParent;
        }
        return {
            top: top,
            left: left
        }
    },
    /*
     此方法直接通過getBoundingClientRect()方法獲得相對於視口的偏移量,
     加上頁面的滾動量,減去clientTop,clientLeft (IE8及更低版本瀏覽器將(2,2)作爲起點座標,
     所以要將值減去起點座標,其他瀏覽器都是已(0,0)作爲起點座標)。
     getBoundingClientRect()方法支持IE,ff3+,safari4+,Orear9,5,Chrome.
     */
    getOffsetRect: function (ele) {
        var box = ele.getBoundingClientRect();
        var body = document.body,
            docElem = document.documentElement;
        //獲取頁面的scrollTop,scrollLeft(兼容性寫法)
        var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop,
            scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
        var clientTop = docElem.clientTop || body.clientTop,
            clientLeft = docElem.clientLeft || body.clientLeft;
        var top = box.top + scrollTop - clientTop,
            left = box.left + scrollLeft - clientLeft;
        return {
            //Math.round 兼容火狐瀏覽器bug
            top: Math.round(top),
            left: Math.round(left)
        }
    },
    /*
     * 獲取任意元素距離body的偏移
     * 對於支持getBoundingClientRect()方法的瀏覽器使用getOffsetRect()方法,不支持的則使用getOffsetSum()方法
     * 參數:ele
     * 用法:var obj = utils.getOffset(ele)
     */
    getOffset: function (ele) {
        if (ele.getBoundingClientRect) {
            return this.getOffsetRect(ele);
        } else {
            return this.getOffsetSum(ele);
        }
    },
    /*
     * 獲取任意元素距離父級元素的偏移
     * 注意父級元素css要加上position
     * 參數:ele
     * 用法:var obj = utils.getRelativeOffset(ele)
     */
    getRelativeOffset: function (ele) {
        var top = ele.offsetTop;
        var left = ele.offsetLeft;
        return {
            top: top,
            left: left
        }
    },
    /*
     * getEleClientWidthAndHeight:計算元素本身的寬高
     * 參數:ele:元素 包含元素的padding
     * clientWidth,clientHeight:元素可視區域尺寸,內邊距以內的減去滾動條自身尺寸後的尺寸,即padding + width(height) - 滾動條自身尺寸,
     * 用法:var obj = utils.getEleClientWidthAndHeight(ele)
     */
    getEleClientWidthAndHeight: function (ele) {
        var w = ele.clientWidth;
        var h = ele.clientHeight;
        return {width: w, height: h}
    },
    /*
     * getEleClientWidthAndHeightContainBorder:計算元素本身的寬高包含邊框
     * 參數:ele:元素 包含元素的padding
     * offsetWidth,offsetHeight:元素包含邊框以內的尺寸,包含滾動條自身尺寸,即border + padding + width(height),
     * */
    getEleClientWidthAndHeightContainBorder: function (ele) {
        var w = ele.offsetWidth;
        var h = ele.offsetHeight;
        return {width: w, height: h}
    }


};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章