一、实现一个瀑布流布局效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>瀑布流布局</title>
<style>
*{
margin: 0px;
padding: 0px;
}
.waterfall{
position: relative;
}
.item{
width: 200px;
position: absolute;
transition: all .6s;
margin: 10px;
color: #383A3F;
text-align: center;
font-weight: 600;
}
.h1{
line-height: 200px;
background: #9DC8C8;
}
.h2{
line-height: 380px;
background: #D499B9;
}
.h3{
line-height: 250px;
background: #D7FFF1;
}
.h4{
line-height: 320px;
background: #F6B352;
}
.h5{
line-height: 450px;
background: #E71D36;
}
</style>
</head>
<body>
<div class="waterfall">
<div class="item h1">
1
</div>
<div class="item h2">
2
</div>
<div class="item h1">
3
</div>
<div class="item h4">
4
</div>
<div class="item h2">
5
</div>
<div class="item h1">
6
</div>
<div class="item h3">
7
</div>
<div class="item h5">
8
</div>
<div class="item h3">
9
</div>
<div class="item h1">
10
</div>
<div class="item h2">
11
</div>
<div class="item h4">
12
</div>
<div class="item h5">
13
</div>
<div class="item h1">
14
</div>
<div class="item h3">
15
</div>
<div class="item h1">
16
</div>
<div class="item h2">
17
</div>
<div class="item h4">
18
</div>
<div class="item h5">
19
</div>
<div class="item h1">
20
</div>
<div class="item h3">
21
</div>
<div class="item h2">
22
</div>
<div class="item h4">
23
</div>
<div class="item h5">
24
</div>
<div class="item h2">
25
</div>
</div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
var Waterfall = {
arrHeight: [],
init: function($container) {
this.$ct = $container;
this.$items = this.$ct.find('.item');
this.itemsWidth = this.$items.first().width();
this.bind();
this.render();
},
bind: function() {
let that = this;
$(window).on('resize', function() {
that.render();
})
},
render: function() {
let that = this;
this.arrInit(this.colNum());
this.$items.each(function() {
that.placeItem($(this));
})
},
colNum: function() {
return Math.floor(this.$ct.width() / this.itemsWidth);
},
arrInit: function(colNum) {
for(let i=0; i<colNum; i++) {
this.arrHeight[i] = 0;
console.log(this.arrHeight);
}
},
placeItem: function($el) {
// 1. 找到arrColHeight的最小值,得到是第几列
// 2. 元素left的值是 列数*宽度
// 3. 元素top的值是 最小值
// 4. 放置元素的位置,把arrColHeight对应的列数的值加上当前元素的高度
let minHeightInfo = this.getIndexOfMinHeight(this.arrHeight),
min = minHeightInfo.min,
idx = minHeightInfo.idx;
$el.css({
left: idx*this.itemsWidth,
top: min
});
this.arrHeight[idx] += $el.outerHeight(true);
},
getIndexOfMinHeight: function(arr) {
console.log(arr);
let min = arr[0],
idx = 0;
for(let i = 1; i< arr.length; i++) {
if(arr[i] < min) {
min = arr[i];
idx = i;
}
};
return {min: min, idx: idx};
}
}
Waterfall.init($('.waterfall'));
</script>
</body>
</html>
二、实现木桶布局效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>木桶布局</title>
<style>
*{
margin: 0;
padding: 0;
}
body{
background: #f1bbba;
}
.barrels{
width: 1000px;
margin: 20px auto 0 auto;
}
.img-row:after{
content:"";
display:block;
clear:both;
}
.img-ct{
float:left;
}
.load{
visibility: hidden;
height: 20px;
}
</style>
</head>
<body>
<div class="barrels">
</div>
<div class="load">我出现就加载</div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
var barrels = {
imgNum: 0,
standardHeight: 0,
rowList: [],
barrelsWidth: 0,
init: function($barrels, imgNum, standardHeight) {
this.$barrels = $barrels;
this.imgNum = imgNum;
this.standardHeight = standardHeight;
this.barrelsWidth = this.$barrels.width();
this.loadImg();
},
render: function(imgInfo) {
let that = this,
barrelsWidth = this.barrelsWidth,
// rowList = this.rowList,
rowWidth = 0,
newImgHeight = 0,
lastImgInfo = imgInfo;
that.rowList.push(lastImgInfo); // 当这行图片没有超过容器宽度时,则一直放到这一行。
$.each(that.rowList, function(index, imgInfo) {
rowWidth += imgInfo.width;
if(rowWidth > barrelsWidth) {
that.rowList.pop();
rowWidth -= imgInfo.width;
// 重新计算缩放比例
newImgHeight = that.standardHeight * barrelsWidth / rowWidth;
that.appendHtml(newImgHeight);
that.rowList = [];
that.rowList.push(lastImgInfo);
}
})
},
appendHtml: function(newHeight) {
let $newRow = $('<div class="img-row"></div>'); // 创建新元素
$.each(this.rowList, function(index, imgInfo) {
let $newImgCt = $('<div class="img-ct"></div>'),
$newImg = imgInfo.targetImg;
$newImg.height(newHeight);
$newImgCt.append($newImg);
$newRow.append($newImgCt);
})
this.$barrels.append($newRow);
},
loadImg: function() {
let that = this;
let imgURLs = this.getURL(this.imgNum);
$.each(imgURLs, function(index, url) {
let img = new Image();
img.src = url;
img.onload = function() {
let originWidth = img.width,
originHeight = img.height,
ratio = originWidth/originHeight; // 宽度根据比例进行缩放
let imgInfo = {
targetImg: $(img),
width: that.standardHeight*ratio,
height: that.standardHeight
}
that.render(imgInfo);
};
})
},
getURL: function(imgNum) {
let width, height, color;
let urls = [];
for(let i = 0; i < imgNum;i++) {
width = Math.floor(Math.random() * 100 + 200);
height = Math.floor(Math.random() * 100 + 200);
color = Math.random().toString(16).substring(2,8);
// urls.push("http://placehold.it/" + width + "x" + height + "/" + color + "/fff");
urls.push("https://unsplash.it/" + width + "/" + height + "/?random");
}
return urls;
},
// 判断.load是否出现
isVisible: function($node) {
var windowHeight = $(window).height(),
scrollTop = $(window).scrollTop(),
offsetTop = $node.offset().top,
nodeHeight = $node.outerHeight(true);
if (windowHeight + scrollTop > offsetTop && scrollTop < offsetTop + nodeHeight) {
return true;
}else{
return false;
}
}
}
// 一开始的时候让图片铺满屏幕
barrels.init($('.barrels'), 20, 200);
var clock;
$(window).on('scroll',function () {
if (clock) {
clearTimeout(clock);
}
clock = setTimeout(function () {
if(barrels.isVisible($('.load'))) {
barrels.init($('.barrels'), 30, 200);
}
},200);
});
</script>
</body>
</html>
三、实现一个新闻瀑布流新闻网站。查看效果
jsonp 接口参数: http://platform.sina.com.cn/slide/album_tech?jsoncallback=func&app_key=1271687855&num=3&page=4
代码
预览