原生JS實現(xiàn)照片瀑布流與懶加載

什么是瀑布流和懶加載

瀑布流是目前比較流行的一種網(wǎng)站頁面布局她君,會在網(wǎng)頁上呈現(xiàn)參差不齊的多欄布局墨技,頁面向下滾動,網(wǎng)頁就會不斷加載數(shù)據(jù)塊并附加至當(dāng)前頁面尾部辐赞。
它的好處就是按需加載:
根據(jù)我們每行圖片的最小高度來動態(tài)的加載圖片
1.首屏加載的是減少向http請求次數(shù)
2.減少瀏覽器以及服務(wù)器的內(nèi)存負(fù)荷

效果圖是這樣滴

demo2.gif

首先看一下布局:

// html部分  img標(biāo)簽部分發(fā)布的時候就變成了![]了,硝训,不知道怎么改
<div id="container">
    <div class="box">
        <div class="box-img">
            ![](images/0.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/1.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/2.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/3.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/4.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/5.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/6.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/7.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/8.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/9.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/10.jpg)
        </div>
    </div>
    <div class="box">
        <div class="box-img">
            ![](images/11.jpg)
        </div>
    </div>
</div>

// CSS部分
    *{
        margin: 0;
        padding: 0;
    }
    #container{
        position: relative;
    }
    .box{
        float: left;
        padding: 5px;
    }
    .box-img{
        padding: 5px;
        border: 1px solid #ccc;
        box-shadow: 0 0 5px #ccc;
        border-radius: 5px;
    }
    .box-img img{
        width: 230px;
        height: auto;
    }

JS部分的邏輯

首先我們得秉承著多人協(xié)作的思想來寫占拍,因為代碼不一定只是給一個人看到,所以為了避免全局污染捎迫,要用函數(shù)模塊化封裝的的思想。如果直接寫在全局表牢,一個項目可能有多個模塊函數(shù)窄绒,命名變量名的時候并不知道其他人的命名,可能會導(dǎo)致bug崔兴。所以全局部分只寫怎么來用這個封裝好了的函數(shù)彰导。

window.onload = function () {
    imgLocation('container', 'box');

    // 模仿數(shù)據(jù)
    var imgData = {"data": [{"src":"24.jpg"},{"src":"25.jpg"},{"src":"26.jpg"},{"src":"27.jpg"},{"src":"28.jpg"}]};
    window.onscroll = function () {
        if (checkFlag()) {
            var cparent = document.getElementById("container");
            for (var i =0; i<imgData.data.length; i++) {
                var ccontent = document.createElement('div');
                ccontent.className = 'box';
                cparent.appendChild(ccontent);
                var boxImg = document.createElement('div');
                boxImg.className = 'box-img';
                ccontent.appendChild(boxImg);
                var img = document.createElement("img");
                img.style.cssText = 'opacity: 0; transform:scale(0)';
                img.src = "images/" + imgData.data[i].src + "";
                boxImg.appendChild(img);
                (function(img){  // 自執(zhí)行程序閉包
                    setTimeout(function(){
                        img.style.cssText="opacity:1;transform:scale(1)";
                    },1000); // 這里的時間自定蛔翅,我是為了測試才寫的1000
                })(img);
            }
            imgLocation('container', 'box');
        }
    }
};

首先我們得定位圖片的位置

function imgLocation(parent, content) {
    // 將parent下面的所有content全部取出
    var cparent = document.getElementById(parent);
    var ccontent = getChildElement(cparent, content);

    // 完善圖片布局
    var imgWidth = ccontent[0].offsetWidth; // 圖片的寬度
    var num = Math.floor(document.documentElement.clientWidth / imgWidth); // 橫排的顯示個數(shù)
    cparent.style.cssText = "width:" + imgWidth * num + "px;margin: 0 auto"; // 給父級添加寬度

    // 計算圖片的高度
    var boxHeightArr = [];
    for (var i=0; i<ccontent.length; i++) {
        if(i < num) {
            boxHeightArr[i] = ccontent[i].offsetHeight;
            console.log(boxHeightArr);
        } else {
            var minHeight =  getMin(boxHeightArr); //最小的高度
            var minIndex = getMinheightLocation(boxHeightArr, minHeight);
            ccontent[i].style.position = 'absolute';
            ccontent[i].style.top = minHeight + 'px';
            ccontent[i].style.left = ccontent[minIndex].offsetLeft + 'px';
            boxHeightArr[minIndex] = boxHeightArr[minIndex] + ccontent[i].offsetHeight; // 更新最小高度
        }
    }
}

這里面有三個函數(shù),一個是得到圖片最小高度的函數(shù)getMin(arr)位谋,為什么要得到最小高度山析?因為我們計算第一排最小高度的圖片之后,第二排的圖片排序是這樣的掏父,第一張排在第一排的最小高度圖片下笋轨,第二張排在第一排倒數(shù)第二高度圖片下,依次排完第二排赊淑,后面的圖片排序都是按照這樣來排爵政。

function getMin(arr) {  // 得到圖片的最小高度
    for(var i=0, ret=arr[0]; i<arr.length; i++) {
        ret = Math.min(ret, arr[i]);  // 依次將最小值賦值給ret,ret始終最小
    }
    return ret;
}

還有一個函數(shù)是得到最小高度圖片索引getMinheightLocation:

function getMinheightLocation(boxHeightArr, minHeight) { // 得到圖片最小高度的序列號
    for (var i in boxHeightArr) {
        if ( boxHeightArr[i] === minHeight) {
            return i;
        }
    }
}

要得到索引位置陶缺,才能將圖片排在這個索引位置下钾挟。
另外一個是得到子集空間的函數(shù),一開始就強(qiáng)調(diào)要用模塊化的思想來做饱岸,我們要做的是函數(shù)之外掺出,全局部分才用html里的id值,函數(shù)只通過傳參來得到里面的東西苫费。

function getChildElement(cparent, content) { // 得到子集空間
    var contentArr = [];
    var allcontent = cparent.getElementsByTagName('*'); // 獲取到所有的元素
    for (var i=0; i<allcontent.length; i++ ) {
        if (allcontent[i].className === content) {
            contentArr.push(allcontent[i]);
        }
    }
    return contentArr;
}

關(guān)于懶加載

懶加載的思想是 頁面的高度 + 滾動的高度 > 最后一張圖片距離瀏覽器頂部的高度汤锨,然后就開始加載圖片。

function checkFlag() {
    var cparent = document.getElementById('container');
    var ccontent = getChildElement(cparent, "box");

    // 數(shù)組最后一個元素的高度距離頂部的距離
    var lastContentHeight = ccontent[ccontent.length-1].offsetTop;
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    var pageHeight = document.documentElement.clientHeight || document.body.scrollHeight;
    if(lastContentHeight < scrollTop + pageHeight){
        return true;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末黍衙,一起剝皮案震驚了整個濱河市泥畅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌琅翻,老刑警劉巖位仁,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異方椎,居然都是意外死亡聂抢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門棠众,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琳疏,“玉大人,你說我怎么就攤上這事闸拿】张危” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵新荤,是天一觀的道長揽趾。 經(jīng)常有香客問我,道長苛骨,這世上最難降的妖魔是什么篱瞎? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任苟呐,我火速辦了婚禮,結(jié)果婚禮上俐筋,老公的妹妹穿的比我還像新娘牵素。我一直安慰自己,他們只是感情好澄者,可當(dāng)我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布笆呆。 她就那樣靜靜地躺著,像睡著了一般闷哆。 火紅的嫁衣襯著肌膚如雪腰奋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天抱怔,我揣著相機(jī)與錄音劣坊,去河邊找鬼。 笑死屈留,一個胖子當(dāng)著我的面吹牛局冰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灌危,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼康二,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了勇蝙?” 一聲冷哼從身側(cè)響起沫勿,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎味混,沒想到半個月后产雹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡翁锡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年蔓挖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馆衔。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡瘟判,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出角溃,到底是詐尸還是另有隱情拷获,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布减细,位于F島的核電站匆瓜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜陕壹,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望树埠。 院中可真熱鬧糠馆,春花似錦、人聲如沸怎憋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绊袋。三九已至毕匀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間癌别,已是汗流浹背皂岔。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留展姐,地道東北人躁垛。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像圾笨,于是被迫代替她去往敵國和親教馆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,745評論 25 707
  • 瀑布流典型網(wǎng)站 花瓣網(wǎng)擂达、堆糖 [目錄] 瀑布流布局原理大體思路具體思路 插件封裝(5步) 動態(tài)渲染需求分析渲染第一...
    頑皮的雪狐七七閱讀 3,929評論 0 6
  • 人生就像一列開往墳?zāi)沟牧熊囃疗蹋吠旧蠒泻芏嗾荆茈y有人至始至終陪你走完全程板鬓,當(dāng)陪你的人要下車時悲敷,即便不舍,也要心存...
    sunny519111閱讀 962評論 0 0
  • A 1分鐘 昨天的新聞報道了一考生高考英語遲到一分鐘穗熬,工作人員拒絕其進(jìn)入考場镀迂。網(wǎng)友們各有說辭,同意有規(guī)矩成方圓的人...
    QueenieEggplant閱讀 269評論 0 0
  • 2017-02-22星期三"育心麗謙時間管理100天挑戰(zhàn)營” 第37天 A唤蔗、今日行動清單 1探遵、【早起匯報 】: 4...
    嘉雁38677閱讀 164評論 0 2