原生JavaScript轮播图的节流

js的防抖与节流

防抖(debounce)

在函数需要频繁触发时,只有当有足够空闲的时间时,才执行一次。就好像在百度搜索时,每次输入之后都有联想词弹出,这个控制联想词的方法就不可能是输入框内容一改变就触发的,他一定是当你结束输入一段时间之后才会触发。

节流(thorttle)

预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。就好像你在淘宝抢购某一件限量热卖商品时,你不断点刷新点购买,可是总有一段时间你点上是没有效果,这里就用到了节流,就是怕点的太快导致系统出现bug。

区别

在发生持续触发事件时,防抖设置事件延迟并在空闲时间去触发事件,而节流则是隔一定的时间触发一次。

原生JavaScript轮播图的节流

原生JavaScript轮播图的节流是为了防止轮播图在不断的点击的操作下,造成内容跑飞与错位的情况。

CSS部分

.lunbo {
    /* slideshow */
    width: 202px;
    height: 188px;
    margin: 100px auto;
    background-color: hotpink;
}

.box {
    /* slideshow的主窗口 */
    border: 1px solid black;
    width: 200px;
    height: 186px;
    position: relative;
}

ul {
    /* 所有图片的列表 */
    margin: 0;
    padding: 0;
    list-style: none;
    position: absolute;
}

li {
    /* 内含img */
    float: left;
}

button {
    /* 滑动按钮 */
    margin: 0;
    padding: 0;
    text-align: center;
    width: 40px;
    height: 20px;
    line-height: 20px;
    font-size: 16px;
    border-radius: 5px;
}

.btnL {
    /* left按钮 */
    position: absolute;
    top: 83px;
    left: 0;
}

.btnR {
    /* right按钮 */
    position: absolute;
    top: 83px;
    right: 0;
}

HTML部分

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./effect.css">
</head>

<body>
    <div class="lunbo">
        <div class="box">
            <ul>
                <li><img src="./image/01.jpg" alt=""></li>
                <li><img src="./image/02.jpg" alt=""></li>
                <li><img src="./image/03.jpg" alt=""></li>
                <li><img src="./image/04.jpg" alt=""></li>
                <li><img src="./image/05.jpg" alt=""></li>
                <li><img src="./image/06.jpg" alt=""></li>
            </ul>
            <button class="btnL">left</button>
            <button class="btnR">right</button>
        </div>
    </div>
    <script src="./slideshow.js">
    </script>
</body>

</html>

JS部分  节流

var btnL = document.getElementsByClassName("btnL")[0];
var btnR = document.getElementsByClassName("btnR")[0];
var box = document.getElementsByClassName("box")[0];
var ul = document.getElementsByTagName("ul")[0];
var liArr = document.getElementsByTagName("li");
// bool为节流设置开关
var bool = true;
// 将ul的width设置为显示窗口的width*li的数量
ul.style.width = liArr.length * box.offsetWidth + "px"
    // 为显示窗口设置溢出隐藏
box.style.overflow = "hidden"
    // 合理的显示或隐藏按钮
box.onmouseenter = function() {
    btnL.style.display = "block"
    btnR.style.display = "block"
};
box.onmouseleave = function() {
    btnL.style.display = "none"
    btnR.style.display = "none"
};
// 为了整体美观将li限制为显示区域的大小
for (var i; i < liArr.length; i++) {
    liArr[i].style.width = box.offsetWidth + "px"
}
btnL.onclick = function() {
    if (ul.offsetLeft < 0) {
        // 节流的关键在于一个函数只有在大于等于执行周期时才执行,周期内调用不执行.
        // 利用开关 在函数执行时关闭再次执行的开关,在函数执行结束的回调中再次开启开关
        if (bool) {
            bool = false
            move(ul, ul.offsetLeft + 200, function fn() {
                    bool = true
                })
                // move 是封装的简易缓动框架
        }
    }
};
btnR.onclick = function() {
    if (ul.offsetLeft < ul.offsetWidth)
        if (bool) {
            bool = false
            move(ul, ul.offsetLeft - 200, function fn() {
                bool = true
            })
        }

}

// 简易缓动框架
function move(dom, left, fn) {
    // 优化写法先清除dom身上的定时器
    // 在有节流的情况下可以不写
    clearInterval(dom.timer);
    dom.timer = setInterval(function() {
        // 获取dom此时所处的位置信息
        var css = parseInt(window.getComputedStyle(dom, null).left)
            // 设置步长
        var need = (left - css) / 10;
        need = need > 0 ? Math.ceil(need) : Math.floor(need);
        // 判断是继续执行还是结束定时器
        if (Math.abs(left - css) <= Math.abs(need)) {
            // 闪现到目标位置
            dom.style.left = left + "px"
            clearInterval(dom.timer);
            if (fn) {
                fn()
            }
        } else {
            //  缓动中
            dom.style.left = css + need + "px"
        }
    }, 100)

}

以上纯属个人看法,如有错误,欢迎大家指出。

 

posted @ 2020-04-28 10:27  Fortuneteller  阅读(403)  评论(0编辑  收藏  举报