JS中关于组件开发

进行组件开发时我们不必依赖于任何框架,我们只需要使用原生JS,实现指向性,目标性极强的逻辑,比如我们开发轮播图组件,我们不需要复杂的运动框架,更不必复杂的选择器轮子。

组件的哲学和通用轮子不一样。通用轮子,要把所有浏览器、所有属性都要封装进来,注重复用、易用。组件开发只针对特定功能,下面是我写的一个简单的轮播图组件。

<!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>
        * {
            margin: 0;
            padding: 0;
        }
        
        img {
            border: none;
        }
        
        .carousel {
            width: 560px;
            height: 300px;
            margin: 100px auto;
            border: 1px solid #000;
            position: relative;
            overflow: hidden;
        }
        
        .carousel .imageList ul {
            list-style: none;
            position: relative;
        }
        
        .carousel .imageList ul li {
            position: absolute;
            top: 0;
            left: 560px;
            width: 560px;
            height: 300px;
        }
        
        .carousel .imageList ul li.first {
            left: 0;
        }
        
        .btns a {
            position: absolute;
            width: 40px;
            height: 40px;
            top: 50%;
            margin-top: -20px;
            background-color: yellow;
            z-index: 999;
        }
        
        .btns a.leftBtn {
            left: 10px;
        }
        
        .btns a.rightBtn {
            right: 10px;
        }
        
        .circles {
            position: absolute;
            bottom: 10px;
            right: 10px;
            width: 150px;
            height: 18px;
        }
        
        .circles ol {
            list-style: none;
        }
        
        .circles ol li {
            float: left;
            width: 18px;
            height: 18px;
            margin-right: 10px;
            border-radius: 50%;
            background-color: pink;
            cursor: pointer;
        }
        
        .circles ol li.cur {
            background-color: purple;
        }
    </style>
</head>

<body>
    <div class="carousel" id="carousel">
    </div>
    <script src='slider.js'></script>

    <script>
        var slider = new Slider({
            'containerId': 'carousel'
        })
    </script>

</body>

</html>
// 需要接收一个JSON对象
// @param containerId 盒子ID   
// @param time 动画执行时长
// @param interval 动画间隔
// @param Tween 动画缓动公式
// @param autoPlay 动画是否自动轮播
// @param autoPlayTime 动画自动轮播时长
// 这里在封装组件时可以根据需求,添加任意参数比如是否不需要左右按钮,是否不需要圆点按钮。。。

function Slider(dataJson) {
    if (!dataJson) {
        throw new Error('请传入参数');
    }
    this.container = document.querySelector('#' + dataJson.containerId) ? document.querySelector('#' + dataJson.containerId) : null;
    this._init();
    this.leftBtn = this.container.querySelector('.leftBtn');
    this.rightBtn = this.container.querySelector('.rightBtn');
    this.imgList = this.container.querySelectorAll('.imageList li');
    this.circleList = this.container.querySelectorAll('.circles li');
    this.time = dataJson.time || 1000;
    this.interval = dataJson.interval || 10;
    this.Tween = dataJson.Tween || function(t, b, c, d) {
        if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
        return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
    }
    this.autoPlay = dataJson.autoPlay || 1;
    this.autoPlayTime = dataJson.autoPlayTime || 1800;
    this.now = 0;
    this.oldNow = NaN;
    this.timer = null;
    this.timer1 = null;
    this._bindEvent();
    this._auto();

}

Slider.prototype._init = function() {
    this.container.innerHTML = [
        "<div class='btns'>",
        "   <a href='javascript:;' class='leftBtn'></a>",
        "   <a href='javascript:;' class='rightBtn'></a>",
        "</div>",
        "<div class='imageList'>",
        "   <ul>",
        "       <li class='first'><a href='#'><img src='images/0.jpg' alt='' /></a></li>",
        "       <li><a href='#'><img src='images/1.jpg' alt='' /></a></li>",
        "       <li><a href='#'><img src='images/2.jpg' alt='' /></a></li>",
        "       <li><a href='#'><img src='images/3.jpg' alt='' /></a></li>",
        "       <li><a href='#'><img src='images/4.jpg' alt='' /></a></li>",
        "   </ul>",
        "</div>",
        "<div class='circles'>",
        "   <ol>",
        "       <li class='cur'></li>",
        "       <li></li>",
        "       <li></li>",
        "       <li></li>",
        "       <li></li>",
        "   </ol>",
        "</div>"
    ].join("");
};
// 添加滚动下一张方法
Slider.prototype._next = function() {
    // 如果动画未执行完则直接退出
    if (this.timer) {
        return;
    };
    this.oldNow = this.now;
    this.now++;
    if (this.now > this.imgList.length - 1) {
        this.now = 0;
    }
    this._animate([{
        'obj': this.imgList[this.oldNow],
        'startPosition': 0,
        'endPosition': -560,
    }, {
        'obj': this.imgList[this.now],
        'startPosition': 560,
        'endPosition': 0,
    }]);
    this._styleCut(this.now);
};

// 添加滚动上一张方法
Slider.prototype._prev = function() {
    if (this.timer) {
        return;
    }
    this.oldNow = this.now;
    this.now--;
    if (this.now < 0) {
        this.now = this.imgList.length - 1;
    }
    this._animate([{
        'obj': this.imgList[this.oldNow],
        'startPosition': 0,
        'endPosition': 560,
    }, {
        'obj': this.imgList[this.now],
        'startPosition': -560,
        'endPosition': 0,
    }]);
    this._styleCut(this.now);

};

// 添加goto方法
Slider.prototype._goto = function(idx) {
    if (this.timer) {
        return;
    }
    this.oldNow = this.now;
    if (idx > this.now) {
        this.now = idx;
        this._animate([{
            'obj': this.imgList[this.oldNow],
            'startPosition': 0,
            'endPosition': -560,
        }, {
            'obj': this.imgList[this.now],
            'startPosition': 560,
            'endPosition': 0,
        }])
    } else if (idx < this.now) {
        this.now = idx;
        this._animate([{
            'obj': this.imgList[this.oldNow],
            'startPosition': 0,
            'endPosition': 560,
        }, {
            'obj': this.imgList[this.now],
            'startPosition': -560,
            'endPosition': 0,
        }])
    }

};

// 添加动画函数
Slider.prototype._animate = function(dataArr) {
    // 声明当前帧
    var currentFrame = 0;
    // 声明总帧率
    var allFrame = this.time / this.interval;
    // 计算变化量
    var delta = dataArr[0].endPosition - dataArr[0].startPosition;
    var self = this;
    clearInterval(this.timer)
    this.timer = setInterval(function() {
        currentFrame++;
        if (currentFrame >= allFrame) {
            clearInterval(self.timer);
            self.timer = null;
        }
        // 老图移出新图进入
        for (var i = 0; i < dataArr.length; i++) {
            dataArr[i].obj.style.left = self.Tween(currentFrame, dataArr[i]['startPosition'], delta, allFrame) + 'px';
        }
    }, this.interval)
}

// 圆点样式切换
Slider.prototype._styleCut = function(idx) {

    for (var i = 0; i < this.circleList.length; i++) {
        this.circleList[i].className = "";
    }
    this.circleList[idx].className = "cur";
};

// 是否自动轮播

Slider.prototype._auto = function() {
    // 如果用户不要自动轮播直接退出
    if (!this.autoPlay) {
        return;
    }
    var self = this;
    this.timer1 = setInterval(function() {
        self._next();
    }, this.autoPlayTime)
};
// 事件绑定
Slider.prototype._bindEvent = function() {
    var self = this;
    this.rightBtn.addEventListener('click', function() {
        self._next();
    });
    this.leftBtn.addEventListener('click', function() {
        self._prev();
    });
    // 圆点按钮绑定
    for (var i = 0; i < this.circleList.length; i++) {
        this.circleList[i].index = i;

        this.circleList[i].addEventListener('click', function() {
            // 不允许用户连续点击不同的按钮
            if (self.timer) {
                return;
            }
            self._goto(this.index);
            self._styleCut(this.index);

        })
    }
    this.container.addEventListener('mouseover', function() {
        clearInterval(self.timer1);
    });
    this.container.addEventListener('mouseout', function() {
        self._auto();
    })
};

 

posted on 2020-02-26 11:33  素心~  阅读(1132)  评论(0编辑  收藏  举报

导航