原生js实现响应式瀑布流布局加防抖

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>waterfall</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        html,
        body {
            height: 100%;
            overflow: auto;
        }

        #container {
            width: 100%;
            height: 100%;
            overflow: auto;
            background-color: gray;
            display: flex;
            justify-content: space-evenly;
            align-items: flex-start;
        }

        .column {
            width: 300px;
        }

        .col-child {
            width: 100%;
            margin-bottom: 10px;
        }
    </style>
</head>

<body>
    <div id="container"></div>
    <script>
        // 防抖
        function debounce(fn, delay = 300) {
            return () => {
                var timer = null
                if (timer) {
                    clearTimeout(timer)
                }
                timer = setTimeout(() => {
                    fn()
                }, delay)
            }
        }

        // 生成随机数
        function random(min, max) {
            return Math.floor(Math.random() * (max - min)) + min
        }

        // 获取 element 的属性
        function getElStyle(el, property) {
            var elStyle = window.getComputedStyle(el)
            var elProperty = elStyle.getPropertyValue(property)
            return elProperty
        }

        // 获取数组最小值下标
        function getMinIndex(arr) {
            var min = Math.min(...arr)
            var minIndex = arr.indexOf(min)
            return minIndex
        }

        // 生成列
        function generateColumn() {
            // 获取瀑布流容器及宽度
            var container = document.getElementById('container')
            var containerWidth = getElStyle(container, 'width')
            // 窗口大小变化时清空瀑布流 DOM 下的所有子节点
            container.innerHTML = ''
            console.log('瀑布流容器宽度', containerWidth)
            // 计算列数
            var column = Math.floor(parseInt(containerWidth) / 310)
            console.log('列数', column)
            if (column > 0) {
                // 循环插入列
                for (let i = 0; i < column; i++) {
                    var element = document.createElement('div')
                    element.className = 'column'
                    container.appendChild(element)
                }
            }
        }

        // 计算最低列并插入 DOM
        function insertDom() {
            // for 循环(插入30次)高度最矮的列,插入图片(没有图片我用元素代替)
            for (let i = 0; i < 30; i++) {
                // 创建要插入的瀑布块儿
                var element = document.createElement('div')
                // 定义瀑布块儿 className
                element.className = 'col-child'
                // 瀑布块儿高度,为了实现瀑布流效果随机生成(100 - 500)
                var randomHeight = random(100, 500) + 'px'
                element.style.height = randomHeight
                var randomColor = `rgb(${random(0, 255)}, ${random(0, 255)}, ${random(0, 255)})`
                element.style.backgroundColor = randomColor
                // 获取所有列的 DOM (伪数组)
                var allColumn = document.querySelectorAll('.column')
                if (allColumn.length) {
                    // 转换成数组
                    var _allColumn = Array.prototype.slice.call(allColumn)
                    // 循环转换获取所有列的高度
                    var allColumnHeight = []
                    for (let i = 0; i < _allColumn.length; i++) {
                        allColumnHeight.push(parseInt(getElStyle(_allColumn[i], 'height')))
                    }
                    // 获取最小高度的下标
                    var minHeightIndex = getMinIndex(allColumnHeight)
                    // 最小高度列插入瀑布块儿
                    allColumn[minHeightIndex].appendChild(element)
                }
            }
        }

        // 窗口 change 事件
        function init() {
            generateColumn()
            insertDom()
        }

        // window 的 onload 及 onresize 事件
        window.onload = debounce(init)
        window.onresize = debounce(init)
    </script>
</body>

</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值