- 什么是瀑布流,說(shuō)話不形象徒欣,直接看圖說(shuō)話
![S55M%73LKAKO@]OZ7D@MH.png](http://upload-images.jianshu.io/upload_images/3361706-6f2520633110a1c3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 原來(lái)瀑布流就是長(zhǎng)這樣,雖然這個(gè)瀑布流有點(diǎn)丑陋切平,但是當(dāng)你當(dāng)你把圖片中的方塊換成圖片磕谅,應(yīng)該會(huì)很贊,同時(shí)隨著你鼠標(biāo)的滾動(dòng)宠纯,圖片會(huì)層次不齊的加載在頁(yè)面上,形成像瀑布一樣的流水效果
- 看完圖后层释,想必你是對(duì)它很感興趣婆瓜,那咱不廢話,直接說(shuō)說(shuō)原理把贡羔!
- 你的視覺(jué)告訴你廉白,啥子瀑布流,不就是每一列的寬度相等乖寒,每一列的寬度不相等猴蹂,沒(méi)什么了不起,戰(zhàn)勝困難就要從戰(zhàn)略上藐視它楣嘁,小樣瀑布流我們還搞不定磅轻,自從我們聽(tīng)了若愚大大的課,解決它簡(jiǎn)直是so easy ,piece of cake,
- 來(lái)把逐虚,我才不怕你----破布流瓢省,枯燥的理論開(kāi)始了
-首先 外面一個(gè)打的div包裹,position:relative;里面的div position:absolute;這是為了有利于用JS來(lái)操作他們的top痊班、left來(lái)更改他們的位置,同時(shí)把這些新建一個(gè)空數(shù)組來(lái)遍歷它們后勤婚,一列為數(shù)組的一個(gè)元素,來(lái)設(shè)置它們的位置涤伐。
第二步馒胆, 我們先把一行放滿,看看到底一行能擺幾個(gè)凝果,用這個(gè)公式就可以了:一行能擺的數(shù)量=窗口可視區(qū)域的寬度/一個(gè)div的寬度祝迂,由于我們給每個(gè)div設(shè)置了margin,所以獲取元素的寬度時(shí)器净,應(yīng)該使用 var $itemWidth=$('.item').outerWidth(true)型雳,它獲取的是寬度=content寬度+padding寬度+border寬度+margin,而不是width().
第三步,我們開(kāi)始來(lái)擺放每個(gè)div把山害,我們會(huì)發(fā)現(xiàn)第一行沒(méi)有什么問(wèn)題纠俭,依次擺放即可,可是到了第二行浪慌,每一行的高度不一冤荆,我該把它放在哪了,沒(méi)事权纤,有規(guī)律可循:這時(shí)钓简,第二行的第一張應(yīng)該放在頁(yè)面上高度最小的div乌妒,同時(shí),下一個(gè)div總是和當(dāng)前隊(duì)列中高度最小的下面外邓,依次如此撤蚊,即,div的水平方向距離為=div數(shù)組索引號(hào)*div固定寬度损话,拴魄,div垂直方向距離=div數(shù)組索引號(hào)對(duì)應(yīng)的值(即當(dāng)前列的圖片高度之和)。div擺放后更新當(dāng)前列的所有圖片總高度席镀。
注意:第三步你也可以理解為匹中,給定一個(gè)數(shù)組,在該數(shù)組中找出成員最小值和該成員在數(shù)組中的索引號(hào)豪诲。
舉個(gè)例子來(lái)說(shuō):有一排人站在你面前顶捷,現(xiàn)在讓你在它們中找個(gè)最矮,正常人都會(huì)這么想屎篱,我先假設(shè)這群人的第1個(gè)人是身高最矮的服赎,然后我拿第1個(gè)人的身高和第2人的身高比較,若是要是第1個(gè)人的身高最矮交播,就繼續(xù)認(rèn)為第1個(gè)人最矮重虑,若是第2人身高更矮,我就扔了第1個(gè)人秦士,拿第2個(gè)人繼續(xù)按照這個(gè)方法比較缺厉,最后肯定能找到里面?zhèn)€子最矮的。
也就是:首先假定數(shù)組中某個(gè)值為最小值隧土,然后用for循環(huán)遍歷數(shù)組中的所有成員和假定最小值比較提针,如果某數(shù)組成員的值小于假定值,則獲取將該值(colSumHeight[i])和對(duì)應(yīng)的索引號(hào)(i)
第四步:設(shè)置初始狀態(tài)數(shù)組曹傀,數(shù)組長(zhǎng)度等于當(dāng)前一行能擺放的圖片數(shù)辐脖,該數(shù)據(jù)記錄每行中每張圖片的高度,數(shù)組的索引號(hào)記錄圖片在每行上第幾列的位置皆愉。每張圖片擺放后嗜价,修改數(shù)組內(nèi)對(duì)應(yīng)索引號(hào)成員的值(即當(dāng)前列的高度之和)
-
破布流原理到此結(jié)束,下面是詳細(xì)的JS代碼幕庐,有興趣的看官可以看看
$(function(){ var waterfall=(function($){ function render(){ //獲取div元素的寬度 var elWidth=$('.item').outerWidth(true), //計(jì)算得到一列放置div的數(shù)量 colNum=parseInt($(window).width()/elWidth), //設(shè)置空數(shù)組久锥,來(lái)存放每一列div的高度 colSumHeight=[]; //遍歷空數(shù)組,添加元素翔脱,并把每一列div的高度設(shè)置為0 //等同于colSumHeight=[0,0,0,0,0] for(var i=0;i<colNum;i++){ colSumHeight.push(0); } //遍歷所有的div,通過(guò)在函數(shù)計(jì)算出每一列的高度 //找出高度之和最小的一列div,接著一次按照這個(gè)方法 //把所有的div擺放完畢 $('.item').each(function(){ var $cur=$(this); var idx=0, minSumHeight=colSumHeight[0]; for(var i=0;i<colSumHeight.length;i++){ if(colSumHeight[i]<minSumHeight){ idx=i; minSumHeight=colSumHeight[i]; } } $cur.css({ left:idx*elWidth, top:minSumHeight }); colSumHeight[idx]=$cur.outerHeight(true)+colSumHeight[idx]; }) } render() //當(dāng)瀏覽器窗口縮放時(shí)奴拦,重新放置計(jì)算一列放置div的數(shù)量 $(window).on('resize',function(){ render(); }) return{ init:render } })(jQuery) waterfall.init(); })