js dan cuenta de la imagen efecto de cascada, cambie los parámetros de configuración con la versión completa del código de análisis

Prefacio:

        Soy un blanco puro, hay muchos lugares que no entienda los grandes ganado tan bien, si es incorrecto, por favor señalar las grandes ganado tratado! hermano agradecido.

        Este artículo es analizar sus nativos JS lograr la imagen efecto de cascada

página de la demanda

 1. 图片之前拥有最小间隙

 2. 图片可以根据浏览器窗口的改变而改变

 3. 需要用到函数节流与函数防抖的知识

estructura HTML


    <div class="container"></div>
    
    <script src="../../plugin/helpers.js"></script>    <!--函数节流与防抖要引用-->
    <script src="../../plugin/waterfall.js"></script>  <!--瀑布流代码-->


Estilos CSS

comportamiento JS

idea general JS
 1. 根据用户传入的配置信息设置图片信息

 2. 配置默认值

 3. 设置页面的图片

 4. 设置父级元素的定位信息

 5. 设置每张图片的left、top值
   <1>.计算一行有几张图片
      定义一个数组,这个数组用来记录每一列下一张的top值
      初始值为[0,0,0,n...]; 数组的每一项为0


   <2>. 设置图片位置时
    (1).得到数组中最小的值,设置top
    (2).更新数组中该项的top值
    (3).得到该项是数组中的第几项,用于计算该项的left值     

 5. 获得水平方向上的距离信息(一行排几张图、最小间隙)

 6. 设置图片的left、top值

    <script>
        // 因为我本地有40张以img开头的所以我直接循环来获得。
        var srcs = [];
        for (var i =0;i <=40; i++ ){
            srcs.push(`img/${i}.jpg`);
        }
        // 用户可以自行配置参数
        myPlugin.createWaterFall({
            minGap: 15,        // 垂直方向的最小间隙
            imgSrcs: srcs,     // 图片的路径数组
            imgWidth: 220,     // 单张图片的宽度
            container: document.querySelector(".container")  // 需要渲染的容器
        });
    </script>


/**
 * 第一步: 创建一个图片瀑布流
 * @param {*} option 参数配置
 */
window.myPlugin.createWaterFall = function (option) {
    // option默认值
    var defaultOption = {
        minGap: 10,               //  图片最小间隙
        imgSrcs: [],              //  图片的路径数组
        imgWidth: 220,            //  单张图片的宽度
        container: document.body  //  需要渲染的容器,如果用户没有传,默认为body
    }
    // 第二步: 对象混合
    var option = Object.assign({}, defaultOption, option);
    // console.log(option);
    var imgs = [];  // 存放所有的图片dom对象。
}



createImg();
// setFatherPosition();


/**
* 第三步: 创建图片
*/
function createImg() {
    for (var i = 0; i < option.imgSrc.length; i++) {
        var img = document.createElement("img"); // 创建图片
        img.src = option.imgSrc[i];              // 设置图片路径
        img.style.width = option.imgWidth + "px";// 设置每张图片宽度
        img.style.position = "absolute";         // 设置图片为绝对定位
        imgs.push(img);                          // 添加到图片数组中
        option.container.appendChild(img);       // 添加图片到container中
    }
}

Si lo ponemos a la posición absoluta le gusta este


Ahora vamos a establecer la inscripción de los padres

    /**    
     * 第四步: 处理父元素,因为图片都是绝对定位的,父元素必须是一个定位元素。
     */
    function handleParent() {
        var style = getComputedStyle(option.container);  // 获取到父级的最终定位
        if (style.position === "static") {               // 如果父级没有定位 (为何要如此定位,因为万一父级有定位的情况下,我们要保证他不被影响)
            option.container.style.position = "relative";// 设置父级为相对定位 
        }
    }


Ahora vamos a establecer el posicionamiento de cada imagen
a continuación, queremos saber cuántas hojas de dibujar una línea recta?
Hay espacio mínimo entre ellos


    /**
    * 第五步: 得到图片水平方向上的信息。
    */
    function getHorizontalInfo() {
        // 5.1 定义一个对象用来存储数据
        var obj = {};
        // 5.2 容器的宽度
        obj.containerWidth = option.container.clientWidth;
        // 5.3 计算一行有多少个图片
        obj.number = (obj.containerWidth + option.minGap) / (option.imgWidth + option.minGap);
        // 5.4 向下取整, 每行的图片只能少不能多。多了他会放不下
        obj.number = Math.floor(obj.number);
        // 5.5 重新计算每一个水平空隙
        // 总宽度-图片的数量*图片的宽度=剩余空间
        obj.gap = (obj.containerWidth - obj.number * option.imgWidth) / (obj.number - 1);
        console.log(obj.gap);
        return obj; // 返回这个对象
    }


Después de obtener las imágenes en la distancia horizontal
que tenemos que configurar su parte superior y los valores de izquierda
escribimos una función setImgPosition


    /**
     * 第六步: 设置每一张图片的坐标
     */
    function setImgPosition() {
        // 6.1 获取水平方向信息保存到info变量中
        var info = getHorizontalInfo();
        // console.log(info);
        // 第七步: 存放每一列下一张图片的top值
        // 7.1 创建数组
        var arr = new Array(info.number);
        // 7.2 填充数组的每一项为0
        arr.fill(0);
        // 7.3 获取所有的图片
        imgs.forEach(function (img) {
            // 设置图片的坐标
            // 7.4 找到数组里面的最小值
            var minTop = Math.min.apply(null, arr);
            // 7.5 图片的纵坐标
            img.style.top = minTop + "px";
            // 7.6 更新数组的top值(最小值拿的是数组的哪一项,找到对应的列编号。再更新)
            var index = arr.indexOf(minTop);
            // 设置数组当前这一项
            //              图片当前的高度  +  垂直方向间隙
            arr[index] += img.clientHeight + info.gap;
            // 横坐标
            img.style.left = index * (option.imgWidth + info.gap) + "px";
        });
    }



SetImgPosition ejecutar la función
obtiene los siguientes efectos


¿Por qué es esto así? Debido a que la imagen se carga de forma asíncrona, han terminado de cargar la altura de la imagen
de él de modo que cada imagen debe ser terminado de cargar dio a re-establecer la altura
y por lo tanto la función setImgPosition no se puede decir en voz alta, que debe ser llamado en el caso de la imagen


            img.onload = function () {
                setImgPosition();
            };


A veces es mejor prevenir algunas fotos al mismo tiempo está casi terminado de cargar
las llamadas demasiado frecuentes setImgPosition la llamada de función
así que tenemos que utilizar la función de anti-vibración para limitar sus llamadas frecuentes
referencia a continuación createImg función de código:


El último paso es cambiar la página de los reordenamientos ventana del navegador que se produzca
, por tanto, añadir al recipiente de un evento escuchar


    // 窗口尺寸变化事件
    var debounce = myPlugin.debounce(setImgPosition, 300);
    window.onresize = function () {
        debounce();
    }


Se adjunta a continuación el código completo


comportamiento JS


if (!window.myPlugin) {
    window.myPlugin = {};
}

/**
 * 第一步: 创建一个图片瀑布流
 * @param {*} option 参数配置
 */
window.myPlugin.createWaterFall = function (option) {
    // option默认值
    var defaultOption = {
        minGap: 10,    // 图片最小间隙
        imgSrcs: [],    // 图片的路径数组
        imgWidth: 220,  // 单张图片的宽度
        container: document.body  // 需要渲染的容器
    }
    // 第二步: 对象混合
    var option = Object.assign({}, defaultOption, option);
    // console.log(option);
    var imgs = [];  // 存放所有的图片dom对象

    // 处理父元素
    handleParent();
    // 3.1 创建图片
    createImgs();

    // 窗口尺寸变化事件
    var debounce = myPlugin.debounce(setImgPosition, 300);
    window.onresize = function () {
        debounce();
    }
    /**
     * 第五步: 设置每一张图片的坐标
     */
    function setImgPosition() {
        // 第七步: 获取水平方向信息
        var info = getHorizontalInfo();
        // console.log(info);
        // 7.1 存放每一列下一张图片的top值
        var arr = new Array(info.number);
        // 7.2
        arr.fill(0);
        // console.log(arr);
        // 7.3 获取所有的图片
        imgs.forEach(function (img) {
            // 设置图片的坐标
            // 7.4 找到数组里面的最小值
            var minTop = Math.min.apply(null, arr);
            // 7.5 图片的坐标
            img.style.top = minTop + "px";
            // 7.6 更新数组的top值(最小值拿的是数组的哪一项,找到对应的列编号。再更新)
            var index = arr.indexOf(minTop);
            // 设置数组当前这一项
            //              图片当前的高度  +  垂直方向间隙
            arr[index] += img.clientHeight + info.gap;
            // 横坐标
            img.style.left = index * (option.imgWidth + info.gap) + "px";
        });
        // 设置容器的高度
        var maxTop = Math.max.apply(null, arr);
        option.container.style.height = maxTop - info.gap + "px";
        
    }

    /**
     * 第六步: 得到图片水平方向上的信息。
     */
    function getHorizontalInfo() {
        // 6.1 定义一个对象用来存储数据
        var obj = {};
        // 6.2 容器的宽度
        obj.containerWidth = option.container.clientWidth;
        // 6.3 计算一行有多少个图片
        obj.number = (obj.containerWidth + option.minGap) / (option.imgWidth + option.minGap);
        // 6.4 向下取整, 每行的图片只能少不能多。
        obj.number = Math.floor(obj.number);
        // 6.5 重新计算每一个水平空隙
        // 总宽度-图片的数量*图片的宽度=剩余空间
        obj.gap = (obj.containerWidth - obj.number * option.imgWidth) / (obj.number - 1);
        console.log(obj.gap);
        return obj;
    }
    /**
     * 第三步: 创建图片
     */
    function createImgs() {
        // 函数节流
        var debounce = myPlugin.debounce(setImgPosition, 50);
        // 循环图片路径数组
        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 = function () {
                // 设置图片元素的坐标
                debounce();
            }
            option.container.appendChild(img);
        }
    }

    /**    
     * 第四步: 处理父元素,因为图片都是绝对定位的,父元素必须是一个定位元素。
     */
    function handleParent() {
        // 如果父元素不是定位元素,则将其变为相对定位元素
        var style = getComputedStyle(option.container);
        // console.log(style.position);
        if (style.position === "static") {
            option.container.style.position = "relative";
        }
    }
}




Supongo que te gusta

Origin www.cnblogs.com/qq4297751/p/12631342.html
Recomendado
Clasificación