摘要:源码地址使用说明注意参数瀑布流外容器瀑布流宽度,如果初始化时外容器未隐藏状态则需使用该参数默认获取外容器宽度子元素选择器,比如样式名元素间的间隔元素间垂直方向间隔,默认使用值元素宽度默认会根据容器宽度自动调整强制元素宽度,
源码地址: 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"]).then(_ => { // change waterfall.change() })
browser
demohttps://capricorncd.github.io...
注意container "s style must be style.position=relative|absolute|fixed
参数optionscontainer: HTMLElement
瀑布流外容器.
containerWidth: Number
瀑布流宽度,如果初始化时外容器未隐藏状态则需使用该参数.
默认获取外容器宽度.
itemSelector: String
子元素选择器,比如 样式名".item-container".
gutter: Number
元素间的间隔.
verticalGutter: Number
元素间垂直方向间隔,默认使用gutter值.
itemWidth: Number
元素宽度, 默认 300, 会根据容器宽度自动调整.
forceItemWidth: Boolean
强制元素宽度,即使用itemWidth作为宽度值,默认 false.
align: String, Optional value left|center|right
强制宽度时,元素显示靠边位置,默认 center.
方法reset()
重置瀑布流初始值
loadMeida(array)
预加载列表数据中的image媒体元素.
array: ["http://a.com/1.jpg", "http://a.com/2.jpg"]
@return promise
change()
列表数据改变后后,通知瀑布流更新元素位置.
源码/** * 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} */ 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
demo: https://github.com/capricornc...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/101879.html
摘要:前言最近在整理基础知识,接触到了几个常用的页面特效,其中觉得用原生实现瀑布流的案例十分有趣,于是与大家分享一下。瀑布流瀑布流,又称瀑布流式布局。通过定位的方式是我们实现瀑布流的最基本的原理,只要我们动态的设置它的值值,就能让它排列。 showImg(https://segmentfault.com/img/remote/1460000012621941?w=1052&h=542); 前...
摘要:使用实现瀑布流并不实用,因为实现的瀑布流都是以列来排列的,这里记录下用实现瀑布流,以及微信小程序中使用左右两列来实现瀑布流效果图原生实现瀑布流文件图片可以自己找点替换下就可以了文件添加阴影的时候,加上会显得更加有点悬浮感文件计算图片列数 使用css实现瀑布流并不实用,因为css实现的瀑布流都是以列来排列的,这里记录下用js实现瀑布流,以及微信小程序中使用左右两列来实现瀑布流 1.效果图...
摘要:一一些闲话作为一个写静态的切图仔,其实日常工作中根本用不上瀑布流这种小清新,毕竟营销页面都是要求抢眼吸睛高大上文案爸爸说啥都对。昨上午闲着没事看到别人写的瀑布流的帖子,觉得很好玩的样子,然后决定上午就写一个试试。。。 一、一些闲话 作为一个写静态的切图仔,其实日常工作中根本用不上瀑布流这种小清新,毕竟营销页面都是要求 抢眼__、__吸睛__、 __高大上 (文案爸爸说啥都对)。 昨上...
摘要:瀑布流布局中的图片有一个核心特点等宽不定等高,瀑布流布局在国内网网站都有一定规模的使用,比如花瓣网等等。那么接下来就基于这个特点开始瀑布流探索之旅。 showImg(https://segmentfault.com/img/remote/1460000013059759?w=640&h=280); 瀑布流布局中的图片有一个核心特点 —— 等宽不定等高,瀑布流布局在国内网网站都有一定规模...
阅读 1945·2021-09-22 16:05
阅读 9117·2021-09-22 15:03
阅读 2857·2019-08-30 15:53
阅读 1683·2019-08-29 11:15
阅读 886·2019-08-26 13:52
阅读 2332·2019-08-26 11:32
阅读 1752·2019-08-26 10:38
阅读 2524·2019-08-23 17:19