zoukankan      html  css  js  c++  java
  • 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 {
                 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;
                 560px;
                height: 300px;
            }
            
            .carousel .imageList ul li.first {
                left: 0;
            }
            
            .btns a {
                position: absolute;
                 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;
                 150px;
                height: 18px;
            }
            
            .circles ol {
                list-style: none;
            }
            
            .circles ol li {
                float: left;
                 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();
        })
    };
  • 相关阅读:
    记坑
    常用模板
    ACM-东北赛划水记
    jzoj 4178游戏
    JZOI 4163
    jzoj 4146踩气球
    jzoj 5589. 缩点
    jzoj 5588 %%%
    jzoj 5571 ffs
    BJOI 2017 Kakuro
  • 原文地址:https://www.cnblogs.com/tengx/p/12365919.html
Copyright © 2011-2022 走看看