虎說:簡(jiǎn)約不簡(jiǎn)單-瀑布流布局

有些事我都以忘記,但我現(xiàn)在還記得,今天要寫博客,從注冊(cè)以來,已經(jīng)隔了3個(gè)月沒有寫(園齡6個(gè)月)
這些時(shí)間在干嘛,node,grunt,angular,react,phonegap...
今天來扯扯一個(gè)好久之前就流行的玩意兒,打開網(wǎng)絡(luò),都是前輩們?cè)? 4年前的文章。技術(shù)不老,現(xiàn)在看來還是有難度的,尤其做優(yōu)化響應(yīng)兼容,更是考驗(yàn)水平


效果圖:

871918-20160723175541044-73249515.jpg

大白話:

1.圖片全部都是絕對(duì)定位absolute,定位技術(shù)由js實(shí)現(xiàn)
2.盒子之間的間距由內(nèi)邊距實(shí)現(xiàn),我不會(huì)告訴你外的box是隱藏的,內(nèi)邊距好計(jì)算
3.圖的寬度固定,高度自適應(yīng),這個(gè)沒啥可說的
4.列的個(gè)數(shù)動(dòng)態(tài)計(jì)算,可以說是半個(gè)自適應(yīng),(為啥是半個(gè),因?yàn)檫@個(gè)簡(jiǎn)單版本不會(huì)在頁(yè)面onresize的時(shí)候進(jìn)行整體重繪)

功能:
  1.下拉滾動(dòng)條更新數(shù)據(jù)
    1.1如何捕捉滾動(dòng)條到達(dá)底部判斷?
    1.2如何進(jìn)行數(shù)據(jù)填充
    1.3重繪方法(重復(fù)使用定位渲染)

2.瀑布流定位渲染
    2.1如何進(jìn)行頁(yè)面的渲染
    2.2如何進(jìn)行盒子的定位(**重點(diǎn))
    2.3盒子的迭代

0.1 開始

DOM結(jié)構(gòu),在任何一個(gè)現(xiàn)代化的coding上面按下tab鍵

#content>.box*10>.info>(.pic>img[href=”$$.jpg”])+.title{this ia a title}

0.2 樣式(只放大容器,看不見的盒子,內(nèi)盒子)

#content{width:auto;height:auto;margin:0 auto;position:relative;}/* 大容器*/.box{width:280px;height:auto;padding:10px;border:none;float:left;}  /* 看不見的盒子 */.info{width:280px;height:auto;border-radius:8px;box-shadow: 0 0 11px #666;background:#fff;} /* 內(nèi)盒子 */

0.3 休息..休息...
架子搭好了,可喜可賀,以后我要用sass和compass寫這該死的樣式表,
項(xiàng)目代建有些費(fèi)力氣,create,compass compile,compass watch,
也知道最多寫完6行代碼,就得ctrl+s一下,那窗口就像啥一樣

1.1 窗口到達(dá)容器底部判斷
思路:混淆點(diǎn)(滾動(dòng)塊底部 && 滾動(dòng)塊頂部 && 滾動(dòng)塊本身)
  if (滾動(dòng)條底部位置 >= 大容器高度offsetHeight){處理}
  看似簡(jiǎn)單,這里有三個(gè)函數(shù)

// 1 獲取當(dāng)前所有BOX的,class
function getClass (wrap,className){ var obj = wrap.getElementsByTagName('*'); //拿到容器下面是有的標(biāo)簽和類名和ID號(hào) var arr = []; for(var i=0; i<obj.length;i++){ //遍歷這些拿到的東西 if(obj[i].className == className){ //開始篩選,拿到是有的盒子標(biāo)簽 arr.push(obj[i]); //將他push進(jìn)一個(gè)數(shù)組里面 }} return arr; }
// 2 function getLastH (){ var warp = document.getElementById('content'); var boxs = getClass(content,'box'); //獲得所有的盒子class return boxs[boxs.length-1].offsetTop + boxs[boxs.length-1].offsetHeight; //返回最后一個(gè)盒子的底部距離文檔頂部的距離 }
// 3 調(diào)用上兩個(gè)函數(shù),最終得到true OR false ,重點(diǎn)就在這里 function getCheck (){ var documentH = document.documentElement.clientHeight; //文檔的高度,單頁(yè)面等于innerHeight var scrollH = document.documentElement.scrollTop || document.body.scrollTop; //滾動(dòng)條距離頂部的距離 //加起來實(shí)際上就是等于滾動(dòng)條底部離文檔頂部的距離, return documentH + scrollH >= getLastH() ? true:false; //總結(jié):監(jiān)聽滾動(dòng)事件,如果當(dāng)前的滾動(dòng)條位置大于等于最后一個(gè)box底部的位置的話返回true };

核心總結(jié):

滾動(dòng)條頂部位置scrollTop + 網(wǎng)頁(yè)可視區(qū)高度clientHeight = 滾動(dòng)條底部距網(wǎng)頁(yè)頂部距離Y

Y >= 最后一個(gè)盒子的BOX.offsetTop  得到滾動(dòng)條到達(dá)底部,開始加載數(shù)據(jù) & 渲染頁(yè)面

1.2 如何進(jìn)行數(shù)據(jù)填充
  一般情況下使用的是JSON或者是數(shù)組格式的數(shù)據(jù),如何填充?
  自己琢磨...
  我使用的是二維數(shù)組,for循環(huán) + arr[i].src完成取出數(shù)據(jù)
  經(jīng)過原生DOM添加到大容器中

//不完整的代碼var data = [ {'src':'01.jpg','title':'this is a title'}, {'src':'02.jpg','title':'this is a title'}, {'src':'03.jpg','title':'this is a title'},];....for(i in data){ var box = document.createElement('div'); box.className = 'box'; wrap.appendChild(box); //創(chuàng)建info var info = document.createElement('div'); info.className = 'info'; box.appendChild(info); //創(chuàng)建pic var pic = document.createElement('div'); pic.className = 'pic'; info.appendChild(pic);};....

1.3 如何進(jìn)行網(wǎng)頁(yè)渲染
  直接跳到下一個(gè)話題,頁(yè)面渲染話題,因?yàn)殇秩痉譃閮纱危?br>   一次頁(yè)面加載
  二次下拉刷新
  三次下拉刷新
  四次...
  使用的都是同一個(gè)大函數(shù)

1.99 休息休息,
  你以后是微信有看頭還是
  原生有看頭還是
  node服務(wù)端有看頭還是
  VR有...

2.1 如何對(duì)頁(yè)面進(jìn)行渲染
  1.計(jì)算頁(yè)面容納列數(shù)
  列數(shù) = 頁(yè)面總寬度clientWidth/單個(gè)box盒子的寬度  //列數(shù)是不是整數(shù)
  列數(shù) = Math.floor(頁(yè)面總寬度clientWidth/單個(gè)box盒子的寬度)   //向下取整

var wrap = document.getElementById(wrap); //獲得容器 var boxs = getClass(content,'box'); //獲取所有的box var boxW = boxs[0].offsetWidth; var colsNum = Math.floor(document.documentElement.clientWidth/boxW); //頁(yè)面的寬度/第一個(gè)box的寬,等于列數(shù) wrap.style.width = boxW * colsNum + 'px'; //外層容器的寬度

2.2 如何進(jìn)行盒子的定位(重點(diǎn))
 大白話:核心思想是將每一列的BOX高度存儲(chǔ)在一個(gè)數(shù)組中,記住是每一列的
     之后獲取數(shù)組中最小的數(shù)字(最矮的那個(gè)),盒子定位top = minHeight & left = 數(shù)組索引(這真是一個(gè)巧妙的設(shè)計(jì))

//主函數(shù)function PBL (wrap,box){ var wrap = document.getElementById(wrap); //獲得容器 var boxs = getClass(content,'box'); //獲取所有的box var boxW = boxs[0].offsetWidth; var colsNum = Math.floor(document.documentElement.clientWidth/boxW); //頁(yè)面的寬度/第一個(gè)box的寬,等于列數(shù) wrap.style.width = boxW * colsNum + 'px'; //外層容器的寬度 var everyH = []; for (var i=0; i<boxs.length; i++ ){ if(i<colsNum){ everyH[i] = boxs[i].offsetHeight; //首先將第一列的盒子的高度全部存儲(chǔ)在數(shù)組中 }else{ var minH = Math.min.apply(null,everyH); //求出在數(shù)組中最小的那一個(gè), var minIndex = getIndex(minH,everyH); //獲得最小高度的那個(gè)索引  //將每一個(gè)遍歷的box設(shè)置樣式,最小高度的那個(gè)就是box的值,最后一個(gè)參數(shù)不確定是都干啥的  setStyle(boxs[i],minH,boxs[minIndex].offsetLeft,i); //最重要的步驟,小朋友,設(shè)置響應(yīng)盒子的top和leeft值 everyH[minIndex] += boxs[i].offsetHeight; //這里的數(shù)組并不會(huì)存儲(chǔ)所有的值,只是存儲(chǔ)列的值,最小列,在不停得更換最小數(shù)據(jù) } }};

//獲取最小數(shù)字的索引function getIndex (minH,everyH){        //獲取索引,遍歷所有在數(shù)組中的索引值,如果等于最小的那個(gè)的話,拿出來    for (index in everyH){        if (everyH[index]  == minH){            return index;        }    }};

//定義盒子的定位style,我引用了jqueryvar getStartNum = 0;    //設(shè)置請(qǐng)求加載的條數(shù)function setStyle (box,top,left,index){    if (getStartNum >= index) return;    $(box).css({        'position' : 'absolute',        'top' : top,        'left' : left,        'opacity' : '1'    });    $(box).stop().animate({        "opacity" : "1"    },999);    getStartNum = index;    //不知道是干啥的}

OK,已經(jīng)完成了99%的工作,興奮吧!!
但是玩轉(zhuǎn)瀑布流可不是一朝一夕的功夫,此版本是一個(gè)簡(jiǎn)單的瀑布流
或許日后會(huì)研究強(qiáng)化版的

2.3 如何進(jìn)行盒子迭代
  這一章我主要是為了騙自己的,工作已經(jīng)完成了!
  返回上一個(gè)話題1.3應(yīng)用主函數(shù)PBL(‘content’,‘box’);
  在最頂端,window.onload = function(){ PBL(‘’content’,‘box’) }
  或者$(document).ready(PBL(‘content’,‘box’))


-------算法看不懂,怎么破T_T------

申明:本文中的觀點(diǎn)只是博主的觀點(diǎn),不代表博客園的以及其他大神的見解,
如果有疏漏那也是正常的,歡迎各行業(yè)大神
前來交流辯駁!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,805評(píng)論 1 92
  • html結(jié)構(gòu) (Emmet) (div.box>div.pic>img[src="images/$.jpg"])*...
    LaBaby_閱讀 661評(píng)論 0 0
  • 移動(dòng)開發(fā)基本知識(shí)點(diǎn) 一.使用rem作為單位 html { font-size: 100px; } @media(m...
    橫沖直撞666閱讀 3,514評(píng)論 0 6
  • H5移動(dòng)端知識(shí)點(diǎn)總結(jié) 閱讀目錄 移動(dòng)開發(fā)基本知識(shí)點(diǎn) calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇閱讀 4,625評(píng)論 0 26
  • 她的肌膚很有彈性,白皙光滑,因?yàn)榧竟?jié)問題皮膚略干燥緊繃。我認(rèn)為戀愛只是某刻短暫的吸引造成錯(cuò)覺般的記憶,仿佛久久等待...
    一頁(yè)小城閱讀 287評(píng)論 0 1