js自学记录

js商城项目——轮播图

2020-09-25  本文已影响0人  璃小灯吖

本前端小白最近在学习js的基础知识,下面记录下一个轮播图的具体写法思路。

1、具体实现效果图



2、主要涉及知识要点

获取元素节点进行Dom事件操作
offset家族获取元素的宽高值
定时器的应用
缓动动画的封装

3、轮播图实现思路方法

1)获取需要的标签元素
// 1. 获取需要的标签
var casualContent = myTool.$('casual_content');
var contentImg = casualContent.children;
var casualControl  = myTool.$('casual_control');
var casualControlBottom = casualControl.children[2];

// 更改背景颜色(后面会用到先写着总是没错的)
var bgColorArr = ['#0037b5','#bd91ff', '#6e02ad', '#10358e', '#f38120'];
var lkCasual = myTool.$('lk_casual');
 lkCasual.style.backgroundColor = bgColorArr[0];
2)创建全局索引,记录当前图片的index值
// 2. 全局索引
var iNow = 0;
3) 动态创建下面的指示器
// 3. 动态创建下面的指示器(也就是那个圆点)
for (let index = 0; index < contentImg.length; index++) {
    var li = document.createElement('li');
    casualControlBottom.insertBefore(li, casualControlBottom.children[0]);

}
4)设置第一个选中
// 4. 让第一个指示器选中
casualControlBottom.children[0].className = 'current';
5) 让除了第一张幻灯片归位
// 5. 让除了第一张幻灯片归位
var scrollImgWidth = casualContent.offsetWidth;
console.log(scrollImgWidth);
for (let index = 1; index < contentImg.length; index++) {
    contentImg[index].style.left = scrollImgWidth + 'px';
    
}
6) 处理左右按钮点击和底部圆点鼠标进入切换图片
var cPrev = casualControl.children[0];
var cNext = casualControl.children[1];

// 点击左边
cPrev.addEventListener('click', function(){
    /**
     * 当前可视区域幻灯片快速右移
     * 下一张图片出现在可视区域左边
     * 让这张幻灯片做动画进入
     */
    myTool.buffer(contentImg[iNow], {'left': scrollImgWidth})
    iNow --;
    if(iNow < 0) {
        iNow = contentImg.length - 1;
    }
    contentImg[iNow].style.left = -scrollImgWidth + 'px';
    myTool.buffer(contentImg[iNow], {'left': 0});
    changeIndex();

    // 改变背景颜色
    lkCasual.style.backgroundColor = bgColorArr[iNow];
})
// 点击右边
cNext.addEventListener('click', function(){
    /**
     * 当前可视区域幻灯片快速左移
     * 下一张图片出现在可视区域右边
     * 让这张幻灯片做动画进入
     */
    myTool.buffer(contentImg[iNow], {'left': -scrollImgWidth})
    iNow ++;
    // 边界处理
    if(iNow > contentImg.length - 1) {
         iNow = 0;
    }
    console.log(contentImg.length,iNow);
    contentImg[iNow].style.left = scrollImgWidth + 'px';
    myTool.buffer(contentImg[iNow], {'left': 0});
    changeIndex();
    // 更换背景颜色
    lkCasual.style.backgroundColor = bgColorArr[iNow];
})
// 底部处理
for (let index = 0; index < casualControlBottom.children.length; index++) {
    // 取出单个li标签
    var bottomLi = casualControlBottom.children[index];
    // 监听鼠标进入
    (function(index){
        bottomLi.addEventListener('mouseover', function (ev) {
            /**
             * 对比索引
             *  鼠标进入大于当前索引相当于点击向右
             *  鼠标进入小于当前索引相当于点击向左
             * */ 
            if (index > iNow) {
                myTool.buffer(contentImg[iNow], {'left': -scrollImgWidth})
                contentImg[iNow].style.left = scrollImgWidth + 'px';    
            }else if(index < iNow){
                myTool.buffer(contentImg[iNow], {'left': scrollImgWidth})
                contentImg[iNow].style.left = -scrollImgWidth + 'px';
            }
            iNow = index;
            
            myTool.buffer(contentImg[iNow], {'left': 0});

            changeIndex();
            lkCasual.style.backgroundColor = bgColorArr[iNow];
        })
    })(index)   
}
7)切换索引下面圆点选中对应图片
// 7. 切换索引的方法
function changeIndex() {
    for (let index = 0; index < casualControlBottom.children.length; index++) {
        casualControlBottom.children[index].className = '';
        casualControlBottom.children[iNow].className = 'current';
    }
}
8)设置定时器
// 8. 设置定时器
var timeId = setInterval(function () {
    autoPlay();
}, 2000)

// 自动播放
function autoPlay() {
    myTool.buffer(contentImg[iNow], {'left': -scrollImgWidth})
    iNow ++;
    // 边界处理
    if(iNow > contentImg.length - 1) {
        iNow = 0;
    }
    console.log(contentImg.length,iNow);
    contentImg[iNow].style.left = scrollImgWidth + 'px';
    myTool.buffer(contentImg[iNow], {'left': 0});
    changeIndex();
    lkCasual.style.backgroundColor = bgColorArr[iNow];
}
9)设置和清除定时器

鼠标进入图片时清除定时器,鼠标移出图片时重启定时器

// 9. 设置和清除定时器
casualContent.parentNode.addEventListener('mouseover', function (evt) {
    clearInterval(timeId);
})

casualContent.parentNode.addEventListener('mouseout', function (evt) {
    // clearInterval(timeId);
    timeId = setInterval(autoPlay, 2000);
})

3、html布局代码

<div class="casual-center">
    <div class="casual-center-w">
        <div id="casual_content" class="content">
            <div class="content-img">
                <a href="#"><img src="images/casual01.jpg" alt=""></a>
            </div>
            <div class="content-img">
            <a href="#"><img src="images/casual02.jpg" alt=""></a>
            </div>
            <div class="content-img">
                <a href="#"><img src="images/casual03.jpg" alt=""></a>
            </div>
            <div class="content-img">
                <a href="#"><img src="images/casual04.jpg" alt=""></a>
            </div>
            <div class="content-img">
                <a href="#"><img src="images/casual05.jpg" alt=""></a>
            </div>
        </div>
        <div  id="casual_control"  class="control">
            <a href="javascript:;" class="c-prev">
                <i class="lk-left"></i>
            </a>
            <a href="javascript:;" class="c-next">
                <i class="lk-right"></i>
            </a>
            <ul class="c-bottom">
                <!-- js根据图片数量动态生成 -->
                <!-- <li class="current"></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li> -->
            </ul>
        </div>
    </div>
</div>

4、css样式

.casual-center {width: 100%;height: 44rem;float: left;}
.casual-center .casual-center-w {margin: 0 17rem 0 21rem; /*定位*/position: relative;overflow: hidden;}
.casual-center .casual-center-w .content { /*background-color: red;*/width: 100%;height: 44rem;}
.casual-center .casual-center-w .content .content-img{width: 100%; height: 100%;position: absolute;}
.casual-center .casual-center-w .content img {width: 100%;height: 100%;cursor: pointer;vertical-align: top;}
.casual-center .casual-center-w .control a {background-color: rgba(0, 0, 0, .4);position: absolute;top: 50%;transform: translateY(-50%);padding: 1rem 0.2rem;}
.casual-center .casual-center-w .control a:hover {background-color: rgba(0, 0, 0, .8);}
.casual-center .casual-center-w .control a.c-prev {left: 0;}
.casual-center .casual-center-w .control a.c-next {right: 0;}
.casual-center .casual-center-w .control a i {font-size: 3rem;}
.casual-center .casual-center-w .control .c-bottom {position: absolute;bottom: 2rem;left: 50%;transform: translateX(-50%);display: flex;}
.casual-center .casual-center-w .control .c-bottom li {width: 1.6rem;height: 1.6rem;background-color: #fff;margin: 0 0.3rem;border-radius: 50%;cursor: pointer;}
.casual-center .casual-center-w .control .c-bottom li.current {background-color: orange;}

5、完整js代码

window.addEventListener('load', function(ev){
    /************轮播图 **************/
    (function(){
        // 1. 获取需要的标签
        var casualContent = myTool.$('casual_content');
        var contentImg = casualContent.children;
        var casualControl  = myTool.$('casual_control');
        var casualControlBottom = casualControl.children[2];

        // 更改背景颜色
        var bgColorArr = ['#0037b5','#bd91ff', '#6e02ad', '#10358e', '#f38120'];
        var lkCasual = myTool.$('lk_casual');
        lkCasual.style.backgroundColor = bgColorArr[0];


        // 2. 全局索引
        var iNow = 0;

        // 3. 动态创建下面的指示器
        for (let index = 0; index < contentImg.length; index++) {
            var li = document.createElement('li');
            casualControlBottom.insertBefore(li, casualControlBottom.children[0]);

        }
        // 4. 让第一个选中
        casualControlBottom.children[0].className = 'current';

        // 5. 让除了第一张幻灯片归位
        var scrollImgWidth = casualContent.offsetWidth;
        console.log(scrollImgWidth);
        for (let index = 1; index < contentImg.length; index++) {
            contentImg[index].style.left = scrollImgWidth + 'px';
            
        }
        // 6. 处理左右按钮点击
        var cPrev = casualControl.children[0];
        var cNext = casualControl.children[1];

        // 点击左边
        cPrev.addEventListener('click', function(){
            /**
             * 当前可视区域幻灯片快速右移
             * 下一张图片出现在可视区域左边
             * 让这张幻灯片做动画进入
             */
            myTool.buffer(contentImg[iNow], {'left': scrollImgWidth})
            iNow --;
            if(iNow < 0) {
                iNow = contentImg.length - 1;
            }
            contentImg[iNow].style.left = -scrollImgWidth + 'px';
            myTool.buffer(contentImg[iNow], {'left': 0});
            changeIndex();

            // 改变背景颜色
            lkCasual.style.backgroundColor = bgColorArr[iNow];
        })

        // 点击右边
        cNext.addEventListener('click', function(){
            /**
             * 当前可视区域幻灯片快速左移
             * 下一张图片出现在可视区域右边
             * 让这张幻灯片做动画进入
             */
            autoPlay();
        })
        
        // 底部处理
        for (let index = 0; index < casualControlBottom.children.length; index++) {
            // 取出单个li标签
            var bottomLi = casualControlBottom.children[index];
            // 监听鼠标进入
            (function(index){
                bottomLi.addEventListener('mouseover', function (ev) {
                    /**
                     * 对比索引
                     *  鼠标进入大于当前索引相当于点击向右
                     *  鼠标进入小于当前索引相当于点击向左
                     * */ 
                    if (index > iNow) {
                        myTool.buffer(contentImg[iNow], {'left': -scrollImgWidth})
                        contentImg[iNow].style.left = scrollImgWidth + 'px';    
                    }else if(index < iNow){
                        myTool.buffer(contentImg[iNow], {'left': scrollImgWidth})
                        contentImg[iNow].style.left = -scrollImgWidth + 'px';
                    }
                    iNow = index;
                    
                    myTool.buffer(contentImg[iNow], {'left': 0});

                    changeIndex();
                    lkCasual.style.backgroundColor = bgColorArr[iNow];
                })
            })(index)
            
            
        }
        
        // 7. 切换索引
        function changeIndex() {
            for (let index = 0; index < casualControlBottom.children.length; index++) {
                casualControlBottom.children[index].className = '';
                casualControlBottom.children[iNow].className = 'current';
            }
        }

        // 8. 设置定时器
        var timeId = setInterval(function () {
            autoPlay();
        }, 2000)

        // 自动播放
        function autoPlay() {
            myTool.buffer(contentImg[iNow], {'left': -scrollImgWidth})
            iNow ++;
            // 边界处理
            if(iNow > contentImg.length - 1) {
                iNow = 0;
            }
            console.log(contentImg.length,iNow);
            contentImg[iNow].style.left = scrollImgWidth + 'px';
            myTool.buffer(contentImg[iNow], {'left': 0});
            changeIndex();
            lkCasual.style.backgroundColor = bgColorArr[iNow];
        }

        // 9. 设置和清除定时器
        casualContent.parentNode.addEventListener('mouseover', function (evt) {
            clearInterval(timeId);
        })

        casualContent.parentNode.addEventListener('mouseout', function (evt) {
            // clearInterval(timeId);
            timeId = setInterval(autoPlay, 2000);
        })
    })()
})

其中用到的myTool的方法

(function (w) {
    w.myTool = {
        $: function (id) {
            return typeof id === 'string' ? document.getElementById(id) : null;
        },
        /**
         * 
         * @param {String} obj 
         * @param {String} attr 
         */
        getStyleAttr: function (obj, attr) {
            if (obj.currentStyle) { // IE 和 opera
                return obj.currentStyle[attr];
            } else {
                return window.getComputedStyle(obj, null)[attr];
            }
        },
        changeCssStyle: function (eleObj, attr, value) {
            eleObj.style[attr] = value;
        },
        /**
         * 
         * @param {String} eleObj 
         * @param {JSON} json 
         * @param {Function} fn 
         */
        buffer: function (eleObj, json, fn) {
            // 1.1 先清后设
            clearInterval(eleObj.timer);
 
            // 1.2 定义变量
            var speed = 0, begin = 0, target = 0, flag = false;
 
            // 1.3 设置定时器
            eleObj.timer = setInterval(function () {
                // 标志 (标签的所有属性有没有执行完动画)
                flag = true;
                for(var key in json){
                    // 获取要做动画属性的初始值
                    if(json.hasOwnProperty(key)) {
                        if(key === 'opacity'){
                            begin = parseInt(myTool.getStyleAttr(eleObj, key) * 100) || 100;
                            target = parseInt(json[key]* 100);
                        }else {
                            begin = parseInt(myTool.getStyleAttr(eleObj, key)) || 0;
                            target = parseInt(json[key]);
                        }
     
                        // 2.3 求出步长
                        speed = (target - begin) * 0.2;
                        speed = (target > begin) ? Math.ceil(speed) : Math.floor(speed);
     
                        // 2.4  动起来
                       if(key === 'opacity'){
                           eleObj.style.opacity = (begin + speed) / 100;
                       }else {
                           eleObj.style[key] = begin + speed + 'px';
                       }
     
                        // 2.5 判断
                        if (begin !== target) {
                            flag = false;
                        }
                    }
                }
 
                // 1.4 清除定时器
                if(flag){
                    clearInterval(eleObj.timer);
                    // 开启另一组动画
                    /* if(fn){
                         fn();
                     }*/
                    fn && fn();
                }
            }, 60);
        }
    };
})(window);

以上写法思路来自网易云课堂【撩课-零基础玩转JavaScript】想要查看视频教程的童鞋可以自行去观看噢(●'◡'●)。

上一篇下一篇

猜你喜欢

热点阅读