<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>纯css实现图片瀑布流title>
<style>
.waterfall_container{
column-count: 3;
column-gap: 0px;
width:60%;
text-align: center;
}
.waterfall_item {
-webkit-column-break-inside: avoid;
break-inside: avoid;
counter-increment: item-counter;
padding-top:5px;
}
.waterfall_item img{
width:90%;
}
.waterfall_item p{
font-size:12px;
text-align: center;
margin:8px 0;
}
@media screen and (max-width:800px){
.waterfall_container{
width:100%;
column-count: 2;
}
}
style>
head>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.common.dev.js">script>
<body>
<div class="waterfall_container" id="app">
<div class="waterfall_item" v-for="item in items">
<img :src="'http://23.106.136.165/files/files/yushun/'+item[0]">
<p>{{item[1]}}p>
div>
div>
body>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
items:[]
},
methods:{
get_result(){
let that=this;
setTimeout(function(){
that.items=[["static/news_images/3536162/20171230113354-3e4ab1e1.jpg", "\u7cbe\u9009\u9762\u79ef72\u5e73\u73b0\u4ee3\u4e8c\u5c45\u5ba2\u5385\u5b9e\u666f\u56fe\u7247\u5927\u5168"], ["static/news_images/3536162/20171230113356-4b0a4dba.jpg", "2018\u7cbe\u900983\u5e73\u65b9\u4e8c\u5c45\u5ba2\u5385\u73b0\u4ee3\u88c5\u4fee\u8bbe\u8ba1\u6548\u679c\u56fe\u7247\u5927\u5168"], ["static/news_images/3536162/20171230113443-ef9a63d4.jpg", "\u7cbe\u900978\u5e73\u7c73\u4e8c\u5c45\u9910\u5385\u73b0\u4ee3\u88c5\u4fee\u6548\u679c\u56fe"], ["static/news_images/3536162/20171230113400-c075a845.jpg", "\u7cbe\u9009\u9762\u79ef86\u5e73\u73b0\u4ee3\u4e8c\u5c45\u5ba2\u5385\u88c5\u4fee\u8bbe\u8ba1\u6548\u679c\u56fe\u7247\u6b23\u8d4f"], ["static/news_images/3536162/20171230113434-a79ca815.jpg", "2018\u7cbe\u9009\u9762\u79ef70\u5e73\u73b0\u4ee3\u4e8c\u5c45\u9910\u5385\u88c5\u4fee\u8bbe\u8ba1\u6548\u679c\u56fe\u7247"], ["static/news_images/3536162/20171230113351-b9200e9f.jpg", "\u70ed\u95e8\u9762\u79ef78\u5e73\u73b0\u4ee3\u4e8c\u5c45\u5ba2\u5385\u88c5\u4fee\u6b23\u8d4f\u56fe\u7247\u5927\u5168"], ["static/news_images/3536162/20171230113419-66a901f7.jpg", "\u7cbe\u900988\u5e73\u7c73\u4e8c\u5c45\u5367\u5ba4\u73b0\u4ee3\u88c5\u4fee\u8bbe\u8ba1\u6548\u679c\u56fe\u7247\u5927\u5168"], ["static/news_images/3536162/20171230113405-090f969e.jpg", "201877\u5e73\u7c73\u4e8c\u5c45\u5ba2\u5385\u73b0\u4ee3\u88c5\u4fee\u5b9e\u666f\u56fe\u7247\u5927\u5168"], ["static/news_images/3536162/20171230113446-c61b8e2a.jpg", "\u70ed\u95e877\u5e73\u7c73\u4e8c\u5c45\u8863\u5e3d\u95f4\u73b0\u4ee3\u8bbe\u8ba1\u6548\u679c\u56fe"], ["static/news_images/3536162/20171230113409-67baab71.jpg", "2018\u73b0\u4ee3\u4e8c\u5c45\u53a8\u623f\u88c5\u4fee\u6548\u679c\u56fe\u7247\u5927\u5168"]];
},1000)
},
},
created(){
this.get_result();//模拟请求数据
},
updated(){
}
})
script>
html>
效果图:
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>js实现图片瀑布流(style:absolute)title>
<style>
.waterfall_container{
width:50%;
}
.waterfall_item {
padding-top:10px;
opacity: 0;
width:33.33%;
}
.waterfall_item img{
width:90%;
}
.waterfall_item p{
font-size:12px;
text-align: center;
margin:5px 0;
}
*{
transition: opacity 0.1s;
}
@media screen and (max-width:800px){
.waterfall_container{
width:100%;
}
.waterfall_item{
width:50%;
}
.waterfall_item p{
font-size:10px;
}
}
style>
head>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.common.dev.js">script>
<body>
<div id="app">
<div class="waterfall_container">
<div class="waterfall_item" v-for="item in items">
<img :src="'http://23.106.136.165/files/files/yushun/'+item[0]" waterfall>
<p>{{item[1]}}p>
div>
div>
div>
body>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
items:[]
},
methods:{
get_result(){
var that=this;
setTimeout(function(){
that.items=[["static/news_images/3536162/20171230113354-3e4ab1e1.jpg", "\u7cbe\u9009\u9762\u79ef72\u5e73\u73b0\u4ee3\u4e8c\u5c45\u5ba2\u5385\u5b9e\u666f\u56fe\u7247\u5927\u5168"], ["static/news_images/3536162/20171230113356-4b0a4dba.jpg", "2018\u7cbe\u900983\u5e73\u65b9\u4e8c\u5c45\u5ba2\u5385\u73b0\u4ee3\u88c5\u4fee\u8bbe\u8ba1\u6548\u679c\u56fe\u7247\u5927\u5168"], ["static/news_images/3536162/20171230113443-ef9a63d4.jpg", "\u7cbe\u900978\u5e73\u7c73\u4e8c\u5c45\u9910\u5385\u73b0\u4ee3\u88c5\u4fee\u6548\u679c\u56fe"], ["static/news_images/3536162/20171230113400-c075a845.jpg", "\u7cbe\u9009\u9762\u79ef86\u5e73\u73b0\u4ee3\u4e8c\u5c45\u5ba2\u5385\u88c5\u4fee\u8bbe\u8ba1\u6548\u679c\u56fe\u7247\u6b23\u8d4f"], ["static/news_images/3536162/20171230113434-a79ca815.jpg", "2018\u7cbe\u9009\u9762\u79ef70\u5e73\u73b0\u4ee3\u4e8c\u5c45\u9910\u5385\u88c5\u4fee\u8bbe\u8ba1\u6548\u679c\u56fe\u7247"], ["static/news_images/3536162/20171230113351-b9200e9f.jpg", "\u70ed\u95e8\u9762\u79ef78\u5e73\u73b0\u4ee3\u4e8c\u5c45\u5ba2\u5385\u88c5\u4fee\u6b23\u8d4f\u56fe\u7247\u5927\u5168"], ["static/news_images/3536162/20171230113419-66a901f7.jpg", "\u7cbe\u900988\u5e73\u7c73\u4e8c\u5c45\u5367\u5ba4\u73b0\u4ee3\u88c5\u4fee\u8bbe\u8ba1\u6548\u679c\u56fe\u7247\u5927\u5168"], ["static/news_images/3536162/20171230113405-090f969e.jpg", "201877\u5e73\u7c73\u4e8c\u5c45\u5ba2\u5385\u73b0\u4ee3\u88c5\u4fee\u5b9e\u666f\u56fe\u7247\u5927\u5168"], ["static/news_images/3536162/20171230113446-c61b8e2a.jpg", "\u70ed\u95e877\u5e73\u7c73\u4e8c\u5c45\u8863\u5e3d\u95f4\u73b0\u4ee3\u8bbe\u8ba1\u6548\u679c\u56fe"], ["static/news_images/3536162/20171230113409-67baab71.jpg", "2018\u73b0\u4ee3\u4e8c\u5c45\u53a8\u623f\u88c5\u4fee\u6548\u679c\u56fe\u7247\u5927\u5168"]];
console.log("get_info_finish");
},1000)
},
getMaxHeight(arr){
return Math.max.apply(null, arr)+"px";
},
getMinHeightIndex(arr){
var minHeight=Math.min.apply(null, arr);
if (!arr.indexOf){
Array.prototype.indexOf=function(obj){
var i=this.length;
while(i-=1){
if(this[i]==obj){
return i;
}
}return -1;
}
}
return arr.indexOf(minHeight);
},
waterFall() {
let imgs = document.querySelectorAll('img[waterfall]');
let gradparentDIV=imgs[0].parentNode.parentNode;
gradparentDIV.style.position="relative";
let gap=0
let pageWidth = gradparentDIV.offsetWidth;
let itemWidth = imgs[0].parentNode.offsetWidth;
let columns = Math.round(pageWidth / (itemWidth + gap));
let top_Arr = [];
let left_Arr = [];
let loaded_count=0;
var that=this;
console.log("all_pictrues_count:"+imgs.length);
for (let i = 0; i < imgs.length; i++) {
var img=new Image();
img.src=imgs[i].src;
img.onload=function(){
var parentDIV=imgs[i].parentNode;
parentDIV.style.position="absolute";
if (loaded_count < columns) {
parentDIV.style.top = 0;
parentDIV.style.left = (itemWidth + gap) * loaded_count + 'px';
top_Arr.push(parentDIV.offsetHeight);
left_Arr.push(parentDIV.style.left);
} else {
var index=that.getMinHeightIndex(top_Arr);
parentDIV.style.top = top_Arr[index] + gap + 'px';
parentDIV.style.left = left_Arr[index];
top_Arr[index] = top_Arr[index] + parentDIV.offsetHeight + gap;
}
parentDIV.style.opacity="1";
gradparentDIV.style.height=that.getMaxHeight(top_Arr);
loaded_count++;
// console.log("loaded_count:"+loaded_count);
// console.log("loaded_index:"+i);
if(imgs.length==loaded_count){
console.log("loaded_all_pictrues");
}
}
}
},
windowResizeLister(){
var that=this;
window.addEventListener("resize",function(){
that.waterFall();
})
}
},
created(){
this.get_result();//模拟请求数据
},
updated(){
this.$nextTick(function () {
this.windowResizeLister();
this.waterFall();
})
}
})
script>
html>
注意:访问demo之前请先清空缓存。
https://huxiaofan1223.coding.me/waterFall/css_waterfall.html
https://huxiaofan1223.coding.me/waterFall/js_waterfall.html
demo1很简单没什么说的,因为js都没有用到。
图片是异步下载的,需要判断图片是否下载完,才能撑开div使其有offsetHeight
for (let i = 0; i < imgs.length; i++) {
var img=new Image();
img.src=imgs[i].src;
img.onload=function(){
do_calculate_and_DOM(); //进行复杂的计算并且操作dom
}
}
加载完一张图片,top即为top_Arr中最小值。不仅要最小值,还要求出索引。需要由索引找出left,并且更新top_Arr
let top_Arr = []; //记录上一行元素的top值,length为每一行的列数。
let left_Arr = []; //记录上一行元素的top值,length为每一行的列数。
/*找出最小值的index*/
getMinHeightIndex(arr){
var minHeight=Math.min.apply(null, arr);//找出最小值
return arr.indexOf(minHeight);
}
/*以下代码放在循环中
dom和更新top_Arr*/
var index=that.getMinHeightIndex(top_Arr);
parentDIV.style.top = top_Arr[index] +'px';
parentDIV.style.left = left_Arr[index];
top_Arr[index] = top_Arr[index] + parentDIV.offsetHeight; //更新top_Arr
过程分析完,其实也不是想象中的那么难
1.Artful_Dodger-多列等宽高度不固定的几种css布局(文档流、浮动、瀑布流、flex、flexbox)
2.Levi丶-原生js实现瀑布流效果