• 28.JavaScript实现简单的图片瀑布流插件


    JavaScript实现简单的图片瀑布流插件

    this.myPlugin = this.myPlugin || {};
    
    /**
     * 制作图片瀑布流
     */
    this.myPlugin.createImgWaterfall = function (option) {
        var defaultOption = {
            minGap: 10, //最小间隙
            imgSrcs: [], //存储图片路径的数组
            imgWidth: 200, //单张图片的宽度
            container: document.body //存储图片瀑布流的容器
        };
        //将传入的参数option和默认的配置defaultOption合并
        option = Object.assign({}, defaultOption, option);
        var imgs = []; //存放所有的图片元素的数组
    
        //处理父元素
        handleParent();
    
        //创建图片元素
        createImgs();
    
        //将setImgPosition设置为防抖函数,
        //所有的图片加载完成后,隔一段时间执行setImgPosition函数
        var viewDebounce = debounce(setImgPosition, 300);
        window.onresize = viewDebounce; //浏览器视口尺寸改变,则重新设置图片位置信息
    
        /**
         * 检查父元素是否是定位元素
         * 不是定位元素,要转变为定位元素
         */
        function handleParent() {
            var style = getComputedStyle(option.container);
            if (style.position === "static") { //没有定位
                option.container.style.position = "relative"; //使用相对定位
            }
        }
    
        /**
         * 为每一张图片创建一个img元素
         * 并且设置img元素的样式
         */
        function createImgs() {
            var imgDebounce = debounce(setImgPosition, 300);
            for (var i = 0; i < option.imgSrcs.length; i++) {
                var img = document.createElement("img");
                img.src = option.imgSrcs[i]; //设置图片路径
                img.style.width = option.imgWidth + "px"; //设置图片宽度
                img.style.position = "absolute"; //设置图片绝对定位
                img.style.transition = ".5s"; //设置图片过渡时间
                imgs.push(img);
                img.onload = imgDebounce; //等图片加载完毕,设置图片位置信息
                option.container.appendChild(img); //加入图片容器
            }
        }
    
        /**
         * 设置每个图片元素的位置信息
         */
        function setImgPosition() {
            //获取图片的水平信息
            var info = getHorizontalInfo();
            console.log(info);
            var arr = new Array(info.imgNum); //存放下一行,每张图片的top值
            arr.fill(0); //数组各项值填充为0
            imgs.forEach(function (img) {
                //设置每张图片的位置信息
                var minTop = Math.min.apply(null, arr); //找到数组中最小的top值
                img.style.top = minTop + "px"; //设置图片的top值
                var index = arr.indexOf(minTop); //找到数组中最小值的下标
                arr[index] += img.clientHeight + info.gap; //设置下张图片的top值
                img.style.left = index * (option.imgWidth + info.gap) + "px"; //设置图片的left值
            });
            //所有图片位置设置好后,计算容器最终的高度
            var maxTop = Math.max.apply(null, arr); //找到最大的top值
            option.container.style.height = maxTop - info.gap + "px";
        }
    
        /**
         * 获取图片的水平信息,包括
         * 容器宽度:填充盒
         * 一行可以放置图片的数量
         * 图片与图片之间的水平和垂直空隙
         */
        function getHorizontalInfo() {
            var obj = {};
            obj.containerWidth = option.container.clientWidth; //存放图片容器的宽度
            //imgWidth*imgNum + minGab*(imgNum - 1) = containerWidth;
            //图片宽度 * 图片数量 + 图片间的最小间隙*(图片数量-1) = 容器总宽度
            //根据上面的公式变形后,得到一行可以放置的图片数量
            obj.imgNum = (obj.containerWidth + option.minGap) / (option.imgWidth + option.minGap);
            obj.imgNum = Math.floor(obj.imgNum); //图片数量要向下取整
            //图片之间的间隙 = (容器总宽度 - 图片宽度*图片数量) / (图片数量 - 1)
            obj.gap = (obj.containerWidth - option.imgWidth * obj.imgNum) / (obj.imgNum - 1);
    
            return obj;
        }
    
        /**
         * 函数防抖,过一段时间后,执行某个函数
         */
        function debounce(callback, time) {
            var timer = null; //计时器
            console.log(timer);
            return function () {
                console.log(timer);
                timer && clearTimeout(timer); //每次执行,重新计时
                var args = arguments;
                timer = setTimeout(function () {
                    callback.apply(null, args);
                }, time);
            }
        }
    };
    myPlugin.js

    功能:

    1).可以自动根据浏览器视口宽度,改变图片瀑布流的宽度

    2).添加了函数防抖功能

    调用图片瀑布流插件:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            .container {
                border: 1px solid #000;
                width: 90%;
                margin: 0 auto;
            }
        </style>
    </head>
    
    <body>
        <div class="container">
    
        </div>
        <script src="./js/myPlugin.js"></script>
        <script>
            var imgSrcs = [];
            for(var i = 1; i <= 40; i++){
                imgSrcs.push(`./image/${i}.jpg`);
            }
            myPlugin.createImgWaterfall({
                imgSrcs: imgSrcs,
                container: document.querySelector(".container") //存储图片瀑布流的容器
            });
        </script>
    </body>
    
    </html>
    index.html

    使用了40张图片的图片最后的效果

  • 相关阅读:
    知乎 : 有什么你认为很简单的问题实际的证明却很复杂?
    民科吧 的 一题 : ∂ f / ∂ x =
    知乎: Lurie 的 derived algebraic geometry 有多重要?
    说说 网友 专业证伪 的 那道 几何题
    在 《数学问题,连接两个点的曲线旋转所成曲面中,面积最小的曲线是什么?》 里 的 讨论
    证明 夹逼定理 和 洛必达法则
    一道数学题 : 数列 { bn } 收敛, 证明 { an } 也收敛
    一道数学题 : f ( 2^x ) + f ( 3^x ) = x , 求 f ( x )
    网友 lzmsunny96 的 一个 分数 分解题
    我 搞了一个 尺规作图 不能 实现 三等分角 的 证明
  • 原文地址:https://www.cnblogs.com/lanshanxiao/p/12832558.html
Copyright © 2020-2023  润新知