<body>
<style>
#waterfall {
position: relative;
}
.waterfall-box {
float: left;
width: 200px;
}
</style>
</body>
<p id="waterfall">
<img src="images/1.png" class="waterfall-box">
<img src="images/2.png" class="waterfall-box">
<img src="images/3.png" class="waterfall-box">
<img src="images/4.png" class="waterfall-box">
<img src="images/5.png" class="waterfall-box">
<img src="images/6.png" class="waterfall-box">
...
</p>
由于未知的 css 知识点,丝袜最长的妹子把下面的空间都占用掉了。。。
接着正文,假如如上图,每排有 5 列,那第 6 张图片应该出现前 5 张图片哪张的下面呢?当然是绝对定位到前 5 张图片高度最小的图片下方。
那第 7 张图片呢?这时候把第 6 张图片和在它上面的图片当作是一个整体后,思路和上述是一致的。代码实现如下:
Waterfall.prototype.init = function () {
...
const perNum = this.getPerNum() // 获取每排图片数
const perList = [] // 存储第一列的各图片的高度
for (let i = 0; i < perNum; i++) {
perList.push(imgList[i].offsetHeight)
}
let pointer = this.getMinPointer(perList) // 求出当前最小高度的数组下标
for (let i = perNum; i < imgList.length; i++) {
imgList[i].style.position = 'absolute' // 核心语句
imgList[i].style.left = `${imgList[pointer].offsetLeft}px`
imgList[i].style.top = `${perList[pointer]}px`
perList[pointer] = perList[pointer] + imgList[i].offsetHeight // 数组最小的值加上相应图片的高度
pointer = this.getMinPointer(perList)
}
} .waterfall-box {
float: left;
width: 200px;
padding-left: 10px;
padding-bottom: 10px;
} window.onscroll = function() {
// ...
if (scrollPX + bsHeight > imgList[imgList.length - 1].offsetTop) {// 浏览器高度 + 滚动距离 > 最后一张图片的 offsetTop
const fragment = document.createDocumentFragment()
for(let i = 0; i < 20; i++) {
const img = document.createElement('img')
img.setAttribute('src', `images/${i+1}.png`)
img.setAttribute('class', 'waterfall-box')
fragment.appendChild(img)
}
$waterfall.appendChild(fragment)
}
} proto.bind = function () {
const bindScrollElem = document.getElementById(this.opts.scrollElem)
util.addEventListener(bindScrollElem || window, 'scroll', scroll.bind(this))
}
const util = {
addEventListener: function (elem, evName, func) {
elem.addEventListener(evName, func, false)
},
} const waterfall = new Waterfall({options})
waterfall.on("load", function () {
// 此处进行 ajax 同步/异步添加图片
}) function eventEmitter() {
this.sub = {}
}
eventEmitter.prototype.on = function (eventName, func) { // 订阅函数
if (!this.sub[eventName]) {
this.sub[eventName] = []
}
this.sub[eventName].push(func) // 添加事件监听器
}
eventEmitter.prototype.emit = function (eventName) { // 发布函数
const argsList = Array.prototype.slice.call(arguments, 1)
for (let i = 0, length = this.sub[eventName].length; i < length; i++) {
this.sub[eventName][i].apply(this, argsList) // 调用事件监听器
}
} function Waterfall(options = {}) {
eventEmitter.call(this)
this.init(options) // 这个 this 是 new 的时候,绑上去的
}
Waterfall.prototype = Object.create(eventEmitter.prototype)
Waterfall.prototype.constructor = Waterfall let isLoading = false
const scroll = function () {
if (isLoading) return false // 避免一次触发事件多次
if (scrollPX + bsHeight > imgList[imgList.length - 1].offsetTop) { // 浏览器高度 + 滚动距离 > 最后一张图片的 offsetTop
isLoading = true
this.emit('load')
}
}
proto.done = function () {
this.on('done', function () {
isLoading = false
...
})
this.emit('done')
} const waterfall = new Waterfall({})
waterfall.on("load", function () {
// 异步/同步加载图片
waterfall.done()
}) 相关推荐:
纯原生JS的瀑布流插件Macy.js使用详解
Jquery瀑布流插件使用介绍_jquery
jQuery瀑布流插件Wookmark使用实例_jquery
以上就是JS代码实现瀑布流插件的详细内容,更多请关注Gxl网其它相关文章!
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did40445