虎说:简约不简单-瀑布流布局

有些事我都以忘记,但我现在还记得,今天要写博客,从注册以来,已经隔了3个月没有写(园龄6个月)
这些时间在干嘛,node,grunt,angular,react,phonegap...
今天来扯扯一个好久之前就流行的玩意儿,打开网络,都是前辈们在3 4年前的文章。技术不老,现在看来还是有难度的,尤其做优化响应兼容,更是考验水平


效果图:

871918-20160723175541044-73249515.jpg

大白话:

1.图片全部都是绝对定位absolute,定位技术由js实现
2.盒子之间的间距由内边距实现,我不会告诉你外的box是隐藏的,内边距好计算
3.图的宽度固定,高度自适应,这个没啥可说的
4.列的个数动态计算,可以说是半个自适应,(为啥是半个,因为这个简单版本不会在页面onresize的时候进行整体重绘)

功能:
  1.下拉滚动条更新数据
    1.1如何捕捉滚动条到达底部判断?
    1.2如何进行数据填充
    1.3重绘方法(重复使用定位渲染)

2.瀑布流定位渲染
    2.1如何进行页面的渲染
    2.2如何进行盒子的定位(**重点)
    2.3盒子的迭代

0.1 开始

DOM结构,在任何一个现代化的coding上面按下tab键

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

0.2 样式(只放大容器,看不见的盒子,内盒子)

#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;} /* 内盒子 */

0.3 休息..休息...
架子搭好了,可喜可贺,以后我要用sass和compass写这该死的样式表,
项目代建有些费力气,create,compass compile,compass watch,
也知道最多写完6行代码,就得ctrl+s一下,那窗口就像啥一样

1.1 窗口到达容器底部判断
思路:混淆点(滚动块底部 && 滚动块顶部 && 滚动块本身)
  if (滚动条底部位置 >= 大容器高度offsetHeight){处理}
  看似简单,这里有三个函数

// 1 获取当前所有BOX的,class
function getClass (wrap,className){ var obj = wrap.getElementsByTagName('*'); //拿到容器下面是有的标签和类名和ID号 var arr = []; for(var i=0; i<obj.length;i++){ //遍历这些拿到的东西 if(obj[i].className == className){ //开始筛选,拿到是有的盒子标签 arr.push(obj[i]); //将他push进一个数组里面 }} 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; //返回最后一个盒子的底部距离文档顶部的距离 }
// 3 调用上两个函数,最终得到true OR false ,重点就在这里 function getCheck (){ var documentH = document.documentElement.clientHeight; //文档的高度,单页面等于innerHeight var scrollH = document.documentElement.scrollTop || document.body.scrollTop; //滚动条距离顶部的距离 //加起来实际上就是等于滚动条底部离文档顶部的距离, return documentH + scrollH >= getLastH() ? true:false; //总结:监听滚动事件,如果当前的滚动条位置大于等于最后一个box底部的位置的话返回true };

核心总结:

滚动条顶部位置scrollTop + 网页可视区高度clientHeight = 滚动条底部距网页顶部距离Y

Y >= 最后一个盒子的BOX.offsetTop  得到滚动条到达底部,开始加载数据 & 渲染页面

1.2 如何进行数据填充
  一般情况下使用的是JSON或者是数组格式的数据,如何填充?
  自己琢磨...
  我使用的是二维数组,for循环 + arr[i].src完成取出数据
  经过原生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); //创建info var info = document.createElement('div'); info.className = 'info'; box.appendChild(info); //创建pic var pic = document.createElement('div'); pic.className = 'pic'; info.appendChild(pic);};....

1.3 如何进行网页渲染
  直接跳到下一个话题,页面渲染话题,因为渲染分为两次,
  一次页面加载
  二次下拉刷新
  三次下拉刷新
  四次...
  使用的都是同一个大函数

1.99 休息休息,
  你以后是微信有看头还是
  原生有看头还是
  node服务端有看头还是
  VR有...

2.1 如何对页面进行渲染
  1.计算页面容纳列数
  列数 = 页面总宽度clientWidth/单个box盒子的宽度  //列数是不是整数
  列数 = Math.floor(页面总宽度clientWidth/单个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); //页面的宽度/第一个box的宽,等于列数 wrap.style.width = boxW * colsNum + 'px'; //外层容器的宽度

2.2 如何进行盒子的定位(重点)
 大白话:核心思想是将每一列的BOX高度存储在一个数组中,记住是每一列的
     之后获取数组中最小的数字(最矮的那个),盒子定位top = minHeight & left = 数组索引(这真是一个巧妙的设计)

//主函数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); //页面的宽度/第一个box的宽,等于列数 wrap.style.width = boxW * colsNum + 'px'; //外层容器的宽度 var everyH = []; for (var i=0; i<boxs.length; i++ ){ if(i<colsNum){ everyH[i] = boxs[i].offsetHeight; //首先将第一列的盒子的高度全部存储在数组中 }else{ var minH = Math.min.apply(null,everyH); //求出在数组中最小的那一个, var minIndex = getIndex(minH,everyH); //获得最小高度的那个索引  //将每一个遍历的box设置样式,最小高度的那个就是box的值,最后一个参数不确定是都干啥的  setStyle(boxs[i],minH,boxs[minIndex].offsetLeft,i); //最重要的步骤,小朋友,设置响应盒子的top和leeft值 everyH[minIndex] += boxs[i].offsetHeight; //这里的数组并不会存储所有的值,只是存储列的值,最小列,在不停得更换最小数据 } }};

//获取最小数字的索引function getIndex (minH,everyH){        //获取索引,遍历所有在数组中的索引值,如果等于最小的那个的话,拿出来    for (index in everyH){        if (everyH[index]  == minH){            return index;        }    }};

//定义盒子的定位style,我引用了jqueryvar getStartNum = 0;    //设置请求加载的条数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,已经完成了99%的工作,兴奋吧!!
但是玩转瀑布流可不是一朝一夕的功夫,此版本是一个简单的瀑布流
或许日后会研究强化版的

2.3 如何进行盒子迭代
  这一章我主要是为了骗自己的,工作已经完成了!
  返回上一个话题1.3应用主函数PBL(‘content’,‘box’);
  在最顶端,window.onload = function(){ PBL(‘’content’,‘box’) }
  或者$(document).ready(PBL(‘content’,‘box’))


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

申明:本文中的观点只是博主的观点,不代表博客园的以及其他大神的见解,
如果有疏漏那也是正常的,欢迎各行业大神
前来交流辩驳!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,748评论 1 92
  • html结构 (Emmet) (div.box>div.pic>img[src="images/$.jpg"])*...
    LaBaby_阅读 639评论 0 0
  • 移动开发基本知识点 一.使用rem作为单位 html { font-size: 100px; } @media(m...
    横冲直撞666阅读 3,466评论 0 6
  • H5移动端知识点总结 阅读目录 移动开发基本知识点 calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇阅读 4,486评论 0 26
  • 她的肌肤很有弹性,白皙光滑,因为季节问题皮肤略干燥紧绷。我认为恋爱只是某刻短暂的吸引造成错觉般的记忆,仿佛久久等待...
    一页小城阅读 269评论 0 1