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();
        })
    };
  • 相关阅读:
    HYSBZ 3813 奇数国
    HYSBZ 4419 发微博
    HYSBZ 1079 着色方案
    HYSBZ 3506 排序机械臂
    HYSBZ 3224 Tyvj 1728 普通平衡树
    Unity 3D,地形属性
    nginx 的naginx 种包含include关键字
    Redis 出现NOAUTH Authentication required解决方案
    mysql 8.0出现 Public Key Retrieval is not allowed
    修改jar包里的源码时候需要注意的问题
  • 原文地址:https://www.cnblogs.com/tengx/p/12365919.html
Copyright © 2011-2022 走看看