javascript瀑布流
哇,瀑布流,是的,不错,不错,真的不错,很好玩的样子,于是自己想玩玩啊,来吧,就玩起。
循序渐进,我这里采用原生的js代码来书写。为了方便大家运行代码,我就全部样式和CSS都写在html里面了,当然还需要图片,我会打包。
来上代码。
直接代码
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>哇,瀑布流啊</title> <style type="text/css"> @media screen and (min-width:1550px){ .waterfall-container { width:1400px; } } @media screen and (max-width:1549px) and (min-width:1366px){ .waterfall-container { width:1200px; } } @media screen and (max-width:1365px) and (min-width:700px) { .waterfall-container { width:500px; } } @media screen and (max-width:699px) { .waterfall-container { width:350px; } } .waterfall-container{ top: 0; float:left; display:inline; position:relative; } .water-molecule { position:absolute; border: solid 1px #ccc; padding: 10px; width: 200px; top: 0px; left: 0px; -webkit-transition: all .7s ease-out .1s; -moz-transition: all .7s ease-out .1s; -o-transition: all .7s ease-out .1s; transition: all .7s ease-out .1s } img { width: 100%; } </style> </head> <body > <div> 哟,好拽的瀑布流!!! </div> <div style="position:relative"> <div style="left:0; float:left; display:inline; width:100px"> <ul id="mediaSet"> <li><a href="#">1300px</a></li> <li><a href="#">1100px</a></li> <li><a href="#">900px</a></li> <li><a href="#">600px</a></li> </ul> </div> <div class="waterfall-container"> <div class="water-molecule"><a href="images/temp_img02.jpg"><img src="images/temp_img02.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img03.jpg"><img src="images/temp_img03.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img04.jpg"><img src="images/temp_img04.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img09.jpg"><img src="images/temp_img09.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img05.jpg"><img src="images/temp_img05.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img06.jpg"><img src="images/temp_img06.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img07.jpg"><img src="images/temp_img07.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img08.jpg"><img src="images/temp_img08.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img09.jpg"><img src="images/temp_img09.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img10.jpg"><img src="images/temp_img10.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img11.jpg"><img src="images/temp_img11.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img12.jpg"><img src="images/temp_img12.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img13.jpg"><img src="images/temp_img13.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img14.jpg"><img src="images/temp_img14.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img15.jpg"><img src="images/temp_img15.jpg"/></a> </div> <div class="water-molecule"><a href="images/temp_img15.jpg"><img src="images/temp_img15.jpg"/></a> </div> </div> </div> <script type="text/javascript"> function minColunmnIndex (arr) { var minColumn = 0; var min = arr[minColumn]; for (var i = 1,len=arr.length; i < len; i++) { var temp = arr[i]; if (temp < min) { minColumn = i; min = temp; }; }; return minColumn; } Object.extend = function(destination, source) { for (var property in source) { destination[property] = source[property]; } return destination; } function waterWall(container,settings){ var _settings = { margin:10, cellClass:"water-molecule" }; if(typeof settings != "undefined"){ _settings = Object.extend(_settings,settings); } var margin = _settings.margin; var boxes = document.getElementsByClassName(_settings.cellClass); var wContainer = container; var boxWidth = boxes[0].offsetWidth + margin; function waterfall () { var columnHeight=[]; var waterFallWith = container.offsetWidth; var n = parseInt(waterFallWith/boxWidth); var columnNum = n == 0 ? 1 : n; var baseLeft = wContainer.offsetLeft; for (var i = 0,l=boxes.length; i <l ; i++) { if (i<columnNum) { columnHeight[i]=boxes[i].offsetHeight+margin; boxes[i].style.top = 0; boxes[i].style.left = i*boxWidth+margin+'px'; } else{ var innsertColumn = minColunmnIndex(columnHeight), imgHeight = boxes[i].offsetHeight+ margin; boxes[i].style.top = columnHeight[innsertColumn]+'px'; boxes[i].style.left = innsertColumn*boxWidth+margin+'px'; columnHeight[innsertColumn] +=imgHeight; }; }; }; var wf = { master: container, waterfall:waterfall } return wf; } var wf = new waterWall(document.getElementsByClassName("waterfall-container").item(0)); window.onload = function(){wf.waterfall();}; window.onresize = function(){ wf.master.style.width = null; wf.waterfall(); }; document.getElementById("mediaSet").addEventListener("click",function(ev){ var link = ev.target, width = link.text; wf.master.style.width = width; wf.waterfall(); },false); </script> </body> </html>
分析:
1. 核心就是waterfall方法,计算当前容器的offsetWith,和定义好的单位元素的宽度以及定义的margin来计算列数,再通过当前索引
2. minColumnIndex来计算当前高度最小的列,然后取改列已经存有的高度作为top的值,用 index * 单位元素的宽度 + margin作为 left的值
3.头部定义媒体查询,做到初始化的时候,自动调整,当然,在resize的时候可以动态重新计算,我这里没有这么做
4. 设置了几个 1300,100, 900, 600几个值,用来点击测试。
源码下载:
https://files.cnblogs.com/files/mouse_in_beijing/PB.zip