页面展示代码
<!-- 外层盒子 -->
<div class="Waterfall wf-content" @scroll="handleScroll">
<!-- 图片外层盒子 遍历图片数组 -->
<div class="wf-item" v-for="(item, index) in animallist" :key="index" @click="summary(item.latinName)">
<!-- @load图片加载完成再触发方法 -->
<!-- <img :src="item.imageUrl" @load="imageonload" alt="" /> -->
<el-image @error="errorImg($event)" v-if="item.imageUrl" @load="imageonload" :src="item.imageUrl" alt=""> </el-image>
<el-image @error="errorImg($event)" v-if="!item.imageUrl" @load="imageonload" :src="defaultImageUrl" alt=""> </el-image>
<div>
<h4>
{{ item.name }}
<el-tooltip effect="light" content="信息来源:云南省生物物种名录">
<i class="el-icon-question" style="color: var(--m-main-color)"></i>
</el-tooltip>
</h4>
<em>{{ item.latinName }}</em>
</div>
</div>
</div>
css
.Waterfall {
width: 100%;
margin: 0 auto;
position: relative;
height: 60vh; /* 设置一个固定的高度 */
overflow-x: hidden; /* 开启垂直滚动 */
overflow-y: auto; /* 开启垂直滚动 */
}
.wf-item {
position: absolute;
border: 5px solid white;
box-shadow: -3px 2px 5px rgba(0, 0, 0, 0.5);
cursor: pointer;
}
.wf-item img {
height: 100%;
width: 100%;
}
方法
handleScroll(event) {
const { scrollTop, clientHeight, scrollHeight } = event.target
// 当滚动条到达底部时,距离顶部的距离加上客户区的高度等于整个滚动区的高度
const isBottom = scrollTop + clientHeight >= scrollHeight
if (isBottom) {
// 滚动条到达底部的操作
//console.log('滚动条已经到达底部');
this.pageNum += 1
getSpeciesByType({ speciesType: this.selectLabel, speciesSelect: this.select, pageNum: this.pageNum, pageSize: this.pageSize }).then((response) => {
if (this.total === this.count) {
this.isLoad = false
this.$message.success('信息已加载完成!暂无更多数据')
}
if (this.isLoad) {
for (let item of response.data.data.rows) {
this.count++
this.animallist.push(item)
}
}
})
}
},
// 图片加载完成之后调用方法中的类传参构建瀑布流页面
imageonload() {
new Water({
// 作用元素
el: '.wf-content',
// 列
column: 6,
// 间距
gap: 20
})
},
errorImg(e) {
// console.log(e.target.src,"法1")
// console.log(e.srcElement.src,"法2")
e.srcElement.src = 'http://172.16.7.153:9000/biomap/duitang.gif'
//这一句没用,如果默认图片的路径错了还是会一直闪屏,在方法的前面加个.once只让它执行一次也没用
e.srcElement.onerror = null //防止闪图
},
新建一个Water.js文件,在页面种引入
export class Water{
// 工厂模式给传入元素配置参数
constructor(options){
this.$options = options
// 最小高度
this.miniHeight = []
// 私有方法
this.__init()
}
__init() {
// 获取外层盒子下的所以子元素 也就是图片外层的盒子
this.items = document.querySelector(this.$options.el).children
// 添加列
this.column = this.$options.column
this.gap = this.$options.gap
// 元素宽度减去当前的间距*3除去当前的列得到元素的宽度 也就是根据页面宽度一行可以放几张图片
this.itemWidth = (document.querySelector(this.$options.el).offsetWidth - this.gap * 3) / this.column
this.__render()
}
__render() {
// 把子元素数组化遍历
[...this.items].forEach((value,index) => {
// 把提取的元素宽度赋值
value.style.width = this.itemWidth + "px"
if (index < this.column) {
value.style.top = "0px"
// 当前元素的宽度加上边距 * 下标
value.style.left = (this.itemWidth + this.gap) * index + "px"
// 把元素的高度push到数组里就是index最小的高度
this.miniHeight.push(value.offsetHeight)
} else {
// 这部分是第二行
this.miniIndex = this.__getMiniIndex()
// 元素的上距离 = 最小上距离 加上边距
value.style.top = this.miniHeight[this.miniIndex] + this.gap + "px"
// 左距离=元素宽度加上边距*索引
value.style.left = (this.itemWidth + this.gap) * this.miniIndex + "px"
this.miniHeight[this.miniIndex] = this.miniHeight[this.miniIndex] + value.offsetHeight + this.gap
}
})
}
__getMiniIndex() {
return this.miniHeight.indexOf(Math.min(...this.miniHeight))
}
}
完整代码如下:
<template>
<div class="Waterfall wf-content" @scroll="handleScroll">
<!-- 图片外层盒子 遍历图片数组 -->
<div class="wf-item" v-for="(item, index) in animallist" :key="index" @click="summary(item.latinName)">
<!-- @load图片加载完成再触发方法 -->
<!-- <img :src="item.imageUrl" @load="imageonload" alt="" /> -->
<el-image @error="errorImg($event)" v-if="item.imageUrl" @load="imageonload" :src="item.imageUrl" alt=""> </el-image>
<el-image @error="errorImg($event)" v-if="!item.imageUrl" @load="imageonload" :src="defaultImageUrl" alt=""> </el-image>
<div>
<h4>
{{ item.name }}
<el-tooltip v-if="select != '1-6'" effect="light" content="信息来源:云南省生物物种名录">
<i class="el-icon-question" style="color: var(--m-main-color)"></i>
</el-tooltip>
<el-tooltip v-if="select === '1-6'" effect="light" content="外来入侵物种名录">
<i class="el-icon-question" style="color: var(--m-main-color)"></i>
</el-tooltip>
</h4>
<em>{{ item.latinName }}</em>
</div>
</div>
</div>
</template>
import { getSpeciesByType } from '@/api/maphttp' //查询图片的接口自行定义
import { Water } from '@/api/Water'
export default {
name: 'SpeciesList',
components: {
RootNav,
Foot
},
data() {
return {
total: 2,
pageNum: 1,
pageSize: 12,
defaultImageUrl: '/defaultImage.jpg',
animallist: [],
count: 0
}
},
created() {
this.$nextTick(() => {
getSpeciesByType({ speciesType: '', speciesSelect: '', pageNum: this.pageNum, pageSize: this.pageSize }).then((response) => {
this.animallist = response.data.data.rows
this.total = response.data.data.total
})
})
},
methods: {
handleScroll(event) {
const { scrollTop, clientHeight, scrollHeight } = event.target
// 当滚动条到达底部时,距离顶部的距离加上客户区的高度等于整个滚动区的高度
const isBottom = scrollTop + clientHeight >= scrollHeight
if (isBottom) {
// 滚动条到达底部的操作
//console.log('滚动条已经到达底部');
this.pageNum += 1
getSpeciesByType({ speciesType: this.selectLabel, speciesSelect: this.select, pageNum: this.pageNum, pageSize: this.pageSize }).then((response) => {
if (this.total === this.count) {
this.isLoad = false
this.$message.success('信息已加载完成!暂无更多数据')
}
if (this.isLoad) {
for (let item of response.data.data.rows) {
this.count++
this.animallist.push(item)
}
}
})
}
},
// 图片加载完成之后调用方法中的类传参构建瀑布流页面
imageonload() {
new Water({
// 作用元素
el: '.wf-content',
// 列
column: 6,
// 间距
gap: 20
})
},
errorImg(e) {
// console.log(e.target.src,"法1")
// console.log(e.srcElement.src,"法2")
e.srcElement.src = 'http://172.16.7.153:9000/biomap/duitang.gif'
//这一句没用,如果默认图片的路径错了还是会一直闪屏,在方法的前面加个.once只让它执行一次也没用
e.srcElement.onerror = null //防止闪图
},
}
<style scoped>
.Waterfall {
width: 100%;
margin: 0 auto;
position: relative;
height: 60vh; /* 设置一个固定的高度 */
overflow-x: hidden; /* 开启垂直滚动 */
overflow-y: auto; /* 开启垂直滚动 */
}
.wf-item {
position: absolute;
border: 5px solid white;
box-shadow: -3px 2px 5px rgba(0, 0, 0, 0.5);
cursor: pointer;
}
.wf-item img {
height: 100%;
width: 100%;
}
</style>