js réalisent effet cascade d'image, changer les paramètres de configuration avec la version complète du code d'analyse

Avant-propos:

        Je suis un blanc pur, il y a beaucoup d'endroits que vous ne comprenez pas les gros bétail si bien, en cas d'erreur, s'il vous plaît indiquer les gros bétail traité! frère Grateful.

        Cet article est d'analyser votre JS natif obtenir un effet de cascade d'image

Page de la demande

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

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

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

la structure HTML


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


Styles CSS

comportement JS

JS idée générale
 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 on le met lui positionnement absolu comme celui-ci


Ensuite, nous voulons mettre l'enregistrement du parent

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


Ensuite , nous voulons régler la position de chaque image
nous voulons savoir combien de feuilles de dessin une seule ligne?
Il y a écart minimum entre les


    /**
    * 第五步: 得到图片水平方向上的信息。
    */
    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; // 返回这个对象
    }


Après avoir obtenu les photos sur la distance horizontale
nous devons définir leur sommet et les valeurs de gauche
écrire une fonction 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 exécuter la fonction a
obtenu les effets suivants


Pourquoi est - ce ainsi? Parce que l'image est chargé de manière asynchrone, avoir une hauteur de chargement fini de l'image
afin que chaque image doit être terminé le chargement lui a donné à mettre re-la hauteur
et donc la fonction setImgPosition ne peut pas appeler, il devrait être appelé en cas de l'image


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


Parfois , il est préférable d'éviter quelques images en même temps est presque fini de charger des
appels trop fréquents setImgPosition l'appel de fonction
donc nous devons utiliser la fonction anti-tremblement de limiter ses appels fréquents
mentionnés ci - dessous fonction Code createImg:


La dernière étape consiste à modifier la page de la fenêtre du navigateur réarrangements de se produire
donc ajouter au conteneur un événement d' écoute


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


Ci-joint le code complet


comportement 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";
        }
    }
}




Je suppose que tu aimes

Origine www.cnblogs.com/qq4297751/p/12631342.html
conseillé
Classement