zoukankan      html  css  js  c++  java
  • 封装一个简单的原生js焦点轮播图插件

    轮播图实现的效果为,鼠标移入左右箭头会出现,可以点击切换图片,下面的小圆点会跟随,可以循环播放(为了方便理解,没有补2张图做无缝轮播)。本篇文章的主要目的是分享封装插件的思路。

    轮播图我一开始是写成非插件形式实现的效果,后来才改成了封装成插件的形式。

    首先要明白轮播图的实现原理和基本布局,大概就是外面有一个容器包裹着(通常是div),容器设置宽高,以及overflow为hidden,超出宽高部分隐藏,

    容器里面又包含着另一个容器,包裹着所有的图片,宽为所有图片的总宽度,ul的position为absolute,通过改变ul的left值的变化来实现图片轮播的效果

     

    所以写好的css样式和html代码如下

      *{margin:0; padding:0; text-decoration: none;}
      #container{height: 400px; width: 600px; overflow: hidden; position:relative;}
      #list{height:400px; width:4200px; position: absolute; z-index:1;}
      img{display:inline-block; float:left;}
      #buttons{position: absolute; width:100px; height:10px; z-index:2; bottom:25px; left: 250px;}
      #buttons span{float: left; border:1px solid #fff; width:10px; height:10px; border-radius:50%; margin-right:5px; color:#333; cursor:pointer;}
      #buttons .on {  background: orangered;}
      .arrow{cursor: pointer; display: none; line-height: 39px; text-align: center; font-size: 36px; font-weight: bold; width: 40px; height: 40px;  position: absolute; z-index: 2; top: 180px; background-color: RGBA(0,0,0,.3); color: #fff;}
      .arrow:hover { background-color: RGBA(0,0,0,.7);}
      #container:hover .arrow{display:block;}
      #prev{left:20px;}
      #next{right:20px;}
    <div id="container">
        <div id="list">
            <img src="img/1.jpg" alt="">
            <img src="img/2.jpg" alt="">
            <img src="img/3.jpg" alt="">
            <img src="img/4.jpg" alt="">
            <img src="img/5.jpg" alt="">
        </div>
        <div id="buttons">
            <span index="1" class="on"></span>
            <span index="2"></span>
            <span index="3"></span>
            <span index="4"></span>
            <span index="5"></span>
        </div>
        <a href="javascript:;" class="arrow" id="prev">&lt;</a>
        <a href="javascript:;" class="arrow" id="next">&gt;</a>
     </div>

     接下来要开始封装插件了!!!

    封装插件的基本思想就是:把要写的代码,封闭到一个自执行函数里面,防止跟外部变量冲突,然后将这个构造函数暴露给window对象,方便我们在外部去访问这个构造函数。

    第一:先写好基础的js结构

    ;(function(window, document){ // 使用一个立即执行函数,把window和document对象传进去
    function Carousel(options){ // 创建构造函数,采用大写驼峰写法的函数是构造函数,跟普通方法区分开来
            
        }
        Carousel.prototype = {  // 重写原型
           
        } 
        window.Carousel = Carousel; // 把构造函数暴露出去,全局可调用
    
    })(window, document)

     第二步:写好默认配置,以及完善构造函数,代码成这样

    (function(window, document){
        let defaultSetting = { // 默认设置
            "width":"500",
            "height":"300"
        }
        function Carousel(options){ // 
             var self = this;  // 在构造函数中使用,this指向新创建的对象Carousel{},常把this保存在self里,因为在不同层级,this的指向可能不同
             self.setting = Object.assign(defaultSetting, options); //合并参数,把默认设置和new对象的时候传进来的options进行合并,options里面设置了的项会覆盖默认设置的
             self.container = document.querySelector(self.setting.container); // 获取最外层的容器
             self.list = document.querySelector("#list"); // 获取包裹img的列表
             self.sliderItems = self.list.getElementsByTagName('img'); // 获取图片集合
             self.buttons = document.querySelector("#buttons").getElementsByTagName('span'); // 获取左右按钮集合
             self.prev = document.querySelector("#prev"); // 前进按钮
             self.next = document.querySelector("#next"); // 后退按钮
             self.index = 1;  // 焦点index初始值是1,指示第一张图片
        }
        Carousel.prototype = {
            
        } 
        window.Carousel = Carousel;
    
    })(window, document)

    第三步,给原型添加方法,这样new出来的对象就默认可以使用这些方法了,完善后的代码长这样

    (function(window, document){
        let defaultSetting = {
            "width":"500",
            "height":"300"
        }
        function Carousel(options){ // 
             var self = this;  
             self.setting = Object.assign(defaultSetting, options); 
             self.container = document.querySelector(self.setting.container); 
             self.list = document.querySelector("#list");
             self.sliderItems = self.list.getElementsByTagName('img');
             self.buttons = document.querySelector("#buttons").getElementsByTagName('span');
             self.prev = document.querySelector("#prev");
             self.next = document.querySelector("#next");
             self.index = 1; 
             self.prev.onclick = function(){  // 点击按钮调用rotate方法切换到上一张
                self.rotate('left');
             }
    
             self.next.onclick = function(){ // 点击按钮调用rotate方法切换到下一张
                self.rotate('right');
             }
    
        }
        Carousel.prototype = {
            rotate: function(dir){  // 定义rotate方法
                let self = this;
                let newLeft; // 变化后的left值
                let selfLeft = self.list.style.left; // 原left值
                let sliderWidth = parseInt(self.setting.width); // 可见视口宽度,这里也是一张图片宽度
                let len = self.sliderItems.length; // 图片总张数
                let totalWidth = len * sliderWidth
                    
                if(dir === 'left'){ // 点击左按钮,往前一张            
                    if(!selfLeft){
                        newLeft = selfLeft + sliderWidth;
                        
                    }else{
                        newLeft = parseInt(selfLeft) + sliderWidth
                        self.index--;
                    }
                    if(newLeft > 0){  // 如果是第一张图片往前切换,则切换到最后一张
                        newLeft = -totalWidth + sliderWidth;
                        self.index = len;
                    }
                    self.list.style.left = newLeft + 'px' // 改变left值
                    showButtons();
                }
                if(dir === 'right'){ // 点击右按钮,往后一张, 则left值增加一个负sliderWidth
                    if(!selfLeft){
                        newLeft = selfLeft - sliderWidth
                            self.index++; 
                    }else{
                        newLeft = parseInt(selfLeft) - sliderWidth
                            self.index++;
                    }
                    if(newLeft <= -totalWidth){ // 
                        newLeft = 0;
                        self.index = 1;
                    }
                    self.list.style.left = newLeft + 'px' // 改变left值
                    showButtons();
                }
                
                function showButtons(){  // rotate方法里面又定义了showButtons方法
                    for(let i=0; i< self.buttons.length; i++){
                        if(self.buttons[i].className === 'on'){
                            self.buttons[i].className = ''; // 清除原圆点高亮状态
                            break;
                        }
                    }
                    self.buttons[self.index-1].className ='on';
                }
            }
        } 
        window.Carousel = Carousel; // 暴露出去,供全局对象使用
    
    })(window, document)

    最后一步就是利用构造函数创建对象了,

    var Carousel = new Carousel({
                container:"#container",
                "600",
                height:"400"
            });

    然后我们就能看到上面说的效果。

    原生js封装轮播图插件就完成了,插件不是非常的完善,主要是为了分享自己一步步封装插件的过程,欢迎留言交流,晚点会放上github链接,可以下载源码~

  • 相关阅读:
    Entity Framework 第十篇 条件查询
    Entity Framework 第九篇 关于自增列的事务处理
    Entity Framework 第八篇 结构优化
    Entity Framework 第七篇 简化排序
    控件截图Cache
    Java基础_自加运算
    Java基础_赋值运算
    Java基础_字符与字符串的运算
    同步和异步
    Application中的name属性
  • 原文地址:https://www.cnblogs.com/daisygogogo/p/9499079.html
Copyright © 2011-2022 走看看