• js原生实现轮播图效果(面向对象编程)


    面向对象编程js原生实现轮播图效果

    1.先看效果图

    轮播效果图

    2.需要实现的功能:

    • 自动轮播
    • 点击左右箭头按钮无缝轮播
    • 点击数字按钮切换图片

    分析:如何实现无缝轮播?
    在一个固定大小的相框里有一个ul标签,其长度是几个图片宽度的总和,通过translateX()的方法来实现左右移动动画。
    如何实现无缝呢?比如有三张图片,可以在把第一张图片通过cloneNode的方法克隆下来放到第三张图片后面。图片顺序 1,2,3,1,看下面的HTML结构,结构中并没有4张图,第四张图是生成的。

    3.html结构

    <!-- ul是图片盒子,ol是数字按钮盒子,最下面的div是左右箭头按钮盒子 -->
    <div class="container">
        <div id="screen">
            <ul>
                <li><img src="./img/1.jpg" alt=""></li>
                <li><img src="./img/2.jpg" alt=""></li>
                <li><img src="./img/3.jpg" alt=""></li>
            </ul>
            <ol>
                <!--<li class="active">1</li>-->
                <!--<li>2</li>-->
                <!--<li>3</li>-->
            </ol>
        </div>
        <div>
            <span>&lt;</span>
            <span>&gt;</span>
        </div>
    </div>
    

    4.功能实现

    4.1 创建对象

    创建一个对象,需要传入一个相框盒子元素,通过这个元素来获取盒子中其他需要的元素,并把这些作为这个Carousel对象的属性:

    function Carousel(el) {
        this.screen = el; // 相框
        this.width = this.screen.offsetWidth; // 相框宽度
        this.ulBox = this.screen.children[0]; // ul盒子
        this.list = this.ulBox.children; // ul下面所有li
        this.olBox = this.screen.children[1]; // 数字按钮盒子
        this.arrow = this.screen.nextElementSibling; // 箭头盒子
        this.leftArraw = this.arrow.children[0]; // 左箭头
        this.rightArraw = this.arrow.children[1]; // 右箭头
        this.index = 0; // 数字按钮的索引
        this.timeId = null; // 定时器的id
        this.activeClass = 'active'; // 数字按钮class名
        this.durtion = '.35s'; // 动画持续时间
    }
    

    4.2动画效果由translateX实现

    // 动画
    Carousel.prototype.animate = function (target) {
        this.ulBox.style.transform = 'translateX(' + target + 'px)'
    };
    

    4.3根据轮播图片个数生成数字按钮节点

    生成节点后,为新生成的节点添加点击事件,实现每次点击根据节点对应的index切换图片,这里实现的需求的第三个功能。

    // 创建节点
    Carousel.prototype.createNodes = function () {
    	let self = this;
    	// 创建按钮节点
    	for (let i = 0; i < self.list.length; i++) {
    	    let liObj = document.createElement('li');
    	    liObj.innerText = i + 1;
    	    self.olBox.appendChild(liObj);
    	
    	    // 为生成的数字按钮添加点击事件
    	    liObj.onclick = function () {
    	        self.index = this.innerText - 1; // 获取当前点击对象的索引值
    	        self.switch_sel();
    	        self.animate(-self.index * self.width);
    	    };
    	}
        // 默认显示第一张图片,第一个数字按钮默认选中状态
        self.olBox.children[0].className = self.activeClass;
        // 克隆第一张图放到ulBox后面,实现无缝轮播
        self.ulBox.appendChild(self.ulBox.children[0].cloneNode(true));
    };
    

    4.4轮播图数字按钮点击切换状态

    因为多次用到这段代码,所有就写成一个方法挂在Carousel对象上了

    // 切换数字按钮的选中状态
    Carousel.prototype.switch_sel = function(){
        let self = this;
        for (let i = 0; i < self.olBox.children.length; i++) {
            self.olBox.children[i].removeAttribute('class');
        }
        self.olBox.children[self.index].className = self.activeClass;
    };
    

    4.5轮播事件,也是点击右箭头的事件

    // 轮播事件
    Carousel.prototype.clickHandle = function () {
        let self = this;
        // 如果是最后一张图,直接跳到第一张
        if (self.index === self.list.length - 1) {
            self.index = 0;
    
            // 当点击到最后一张时直接跳到第一张
            self.ulBox.style.transitionDuration = '0s';
            self.animate(-self.index * self.width);
        }
    
        // 必须有时间延迟,否则图片跳转切换不成功,因为self.animate()没有来得及执行就被后面的self.animate()函数覆盖了。
        setTimeout(function () {
            self.ulBox.style.transitionDuration = self.durtion;
            self.index++;
            self.animate(-self.index * self.width);
    
            // 如果是最后一张图,则去掉最后一个的class属性,切换到第一个
            if (self.index === self.list.length - 1) {
                self.olBox.children[self.olBox.children.length - 1].removeAttribute('class');
                self.olBox.children[0].className = self.activeClass;
            } else { // 切换当前选中状态
                self.switch_sel();
            }
        }, 20);
    };
    

    4.6事件绑定

    为左右箭头点击绑定事件,同时当鼠标hover在相框上时自动轮播取消,鼠标离开相框时自动轮播开始执行。

    // 事件绑定
    Carousel.prototype.bindEvent = function () {
        let self = this;
        // 又点击下一张
        self.rightArraw.onclick = function () {
            self.clickHandle();
        };
        // 左点击上一张
        self.leftArraw.onclick = function(){
            if(self.index === 0){
                self.index = self.list.length - 1;
    
                // 直接跳到最后一张
                self.ulBox.style.transitionDuration = '0s';
                self.animate(-self.index * self.width);
            }
    
            setTimeout(function(){
                self.ulBox.style.transitionDuration = self.durtion;
                self.index--;
                self.animate(-self.index * self.width);
                self.switch_sel();
            }, 20);
        };
    
        // 鼠标悬停清除定时器
        self.screen.parentElement.onmouseover = function(){
            self.timeId && clearInterval(self.timeId);
            self.arrow.style.display = 'flex';
    
        };
        // 鼠标离开打开定时器
        self.screen.parentElement.onmouseout = function(){
            self.timeId = setInterval(self.clickHandle.bind(self), 2000);
            self.arrow.style.display = 'none';
        }
    };
    

    4.7初始化方法

    初始化方法中创建节点,绑定事件,同时设定定时器实现自动轮播效果。

    // 初始化
    Carousel.prototype.init = function () {
        this.createNodes();
        this.bindEvent();
        this.timeId = setInterval(this.clickHandle.bind(this), 2000);
        // 注意这里要bind(this) 否则clickHandle中的this指向window
    };
    

    4.8实例化Carousel对象,大功告成

    实例化一个轮播图对象,然后调该对象的init方法。
    只要html结构相同,只需要传入不同的相框元素,就可以在同一个页面中实例化多个轮播图对象。也就是说,同一个页面的多处轮播效果。

    let carousel = new Carousel(document.getElementById('screen'));
    carousel.init();
    

    5备注

    全部的代码和css样式可参考我的github中的轮播图仓库,菜鸟程序猿一枚,程序设计如果有不妥的地方欢迎提出意见或建议,当然啦,如果你喜欢并star了我的这个仓库,我会很开心的 : )
    [1]: https://github.com/jiangleiundo/carousel

  • 相关阅读:
    cmd开启3389,无需重启!
    x86的控制寄存器CR0,CR1,CR2,CR3
    x64下fs的角色已经换成了gs
    在win64里,只有一种调用约定
    fs寄存器
    【转】C++ 编译器的函数名修饰规则
    windbg ida需要symbols
    WIN7-X64内核模式下编程实现导出表列表查看
    VS2010+WDK配置要点
    比特币 —— 学习笔记(一)
  • 原文地址:https://www.cnblogs.com/codebook/p/10817563.html
Copyright © 2020-2023  润新知