原生JavaScript 瀑布流 实现 zx-waterfall
栏目: JavaScript · 发布时间: 5年前
内容简介:源码地址:InstallES6+
源码地址: https://github.com/capricornc...
使用说明
Install zx-waterfall
using npm
npm i --save zx-waterfall
ES6+
import ZxWaterfall from 'zx-waterfall' const waterfall = new ZxWaterfall({ // HTMLElement, waterfall items's outer container container: document.getElementById('zxWaterfall'), // children item selector, eg. '.item-container' itemSelector: '.item-wrapper', // item's spacing, unit px gutter: 20, // item's width itemWidth: 300 }) // reset waterfall.reset() // loaMedias waterfall.loadMedia(['http://xx.com/aaa.jpg']) // change waterfall.change()
browser
<script src="path/zx-waterfall.min.js"></script>
demo
https://capricorncd.github.io...
注意
-
container
's style must bestyle.position=relative|absolute|fixed
参数options
-
container:
HTMLElement
瀑布流外容器.
-
containerWidth:
Number
瀑布流宽度,如果初始化时外容器未隐藏状态则需使用该参数.
默认获取外容器宽度.
-
itemSelector:
String
子元素选择器,比如 样式名'.item-container'.
-
gutter:
Number
元素间的间隔.
-
verticalGutter:
Number
元素间垂直方向间隔,默认使用gutter值.
-
itemWidth:
Number
元素宽度, 默认
300
, 会根据容器宽度自动调整. -
forceItemWidth:
Boolean
强制元素宽度,即使用itemWidth作为宽度值,默认
false
. -
align:
String
, Optional valueleft|center|right
强制宽度时,元素显示靠边位置,默认
center
.
源码
/** * preload image * @param url * @param handler */ function loadImage (url, handler) { let $el = document.createElement('img') $el.src = url $el.onload = handler $el.onerror = handler $el = null } /** * to int * @param m * @returns {number} */ function int (m) { let n = parseInt(m) return isNaN(n) ? 0 : n } /** * convert pseudoArray to array * @param pseudoArray * @param index * @returns {T[]} */ function slice (pseudoArray, index) { return Array.prototype.slice.call(pseudoArray, int(index)) } // default options const DEF_OPTIONS = { // HTMLElement, waterfall items's outer container container: null, // container's width, container are hidden when initialized // default get container offsetWidth when it's visible containerWidth: 0, // children item selector, eg. '.item-container' itemSelector: '', // item's spacing, unit px gutter: 20, // item's vertical spacing, default use gutter's value verticalGutter: 0, // item's width itemWidth: 300, // force item width forceItemWidth: false, // Horizontal align when forceItemWidth is true align: 'center' } /** * ZxWaterfall */ class ZxWaterfall { /** * constructor * @param opts */ constructor (opts) { opts = Object.assign({}, DEF_OPTIONS, opts) // check container if (!opts.container || opts.container.nodeType !== 1) { throw new TypeError(`Instancing parameter 'container' is not HTMLElement.`) } // check itemSelector if (!opts.itemSelector || typeof opts.itemSelector !== 'string') { throw new TypeError(`Instancing parameter 'itemSelector' is null or is't a string.`) } // check verticalGutter if (!opts.verticalGutter) { opts.verticalGutter = opts.gutter } // item number this.count = 0 this.opts = opts this._init() // clone this.reset this._resetClone = this.reset.bind(this) window.addEventListener('resize', this._resetClone) } /** * initialization * @private */ _init () { let opts = this.opts // container width let containerWidth = int(opts.containerWidth) || opts.container.offsetWidth // column number let columnNum = Math.floor(containerWidth / (opts.itemWidth + opts.gutter)) // opts.itemWidth when opts.forceItemWidth = true // else use compute new width this.itemWidth = opts.forceItemWidth ? opts.itemWidth : (containerWidth - (columnNum + 1) * opts.gutter) / columnNum // column current height array this.columns = Array(columnNum) this.columns.fill(0, 0) // offset left when forceItemWidth=true this.offsetLeft = 0 if (opts.forceItemWidth) { let residualSpaceWidth = containerWidth - (this.itemWidth + opts.gutter) * columnNum - opts.gutter switch (opts.align) { case 'center': this.offsetLeft = residualSpaceWidth / 2 break case 'right': this.offsetLeft = residualSpaceWidth break } } } /** * set items position * @private */ _setPosition () { let opts = this.opts // get new item elements let $childs = slice(opts.container.querySelectorAll(opts.itemSelector), this.count) // console.log(this.count, $childs) let len = $childs.length // reset this.count value this.count += len // handle new $item let i, $item for (i = 0; i < len; i++) { $item = $childs[i] if (!$item) continue $item.style.position = 'absolute' $item.style.width = this.itemWidth + 'px' $item.style.display = 'inline-block' // get columns min value let min = Math.min.apply(null, this.columns) let index = this.columns.findIndex(val => val === min) // set $item position $item.style.top = `${min + opts.verticalGutter}px` $item.style.left = `${this.offsetLeft + (this.itemWidth + opts.gutter) * index + opts.gutter}px` // reset waterfall current column height value let itemHeight = $item.offsetHeight this.columns[index] = min + itemHeight + opts.verticalGutter // update container new min height style // opts.container.style.minHeight = Math.max.apply(null, this.columns) + opts.verticalGutter + 'px' } } /** * container's items number change */ change () { // reset postion, when new item element append to container, or remove this._setPosition() } /** * reset */ reset () { this.count = 0 this._init() this._setPosition() } /** * preload media items * @param arr media source urls array * @returns {Promise<any>} */ loadMedia (arr) { return new Promise(resolve => { if (Array.isArray(arr) && arr.length) { let len = arr.length let count = 0 /* eslint-disable */ arr.forEach(url => { loadImage(url, () => { count++ if (len === count) resolve() }) }) } else { resolve() } }) } /** * destroy * removeEventListener window resize */ destroy () { window.removeEventListener('resize', this._resetClone) } } export default ZxWaterfall
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Python Algorithms
Magnus Lie Hetland / Apress / 2010-11-24 / USD 49.99
Python Algorithms explains the Python approach to algorithm analysis and design. Written by Magnus Lie Hetland, author of Beginning Python, this book is sharply focused on classical algorithms, but it......一起来看看 《Python Algorithms》 这本书的介绍吧!