• js 简单的滑动4


    js 简单的滑动教程(四)

     
    作者:Lellansin 转载请标明出处,谢谢

    在大概的了解滑动的基本原理和怎么去实现之后,现在我们将更深入的去讨论js的滑动。
        相信细心的朋友应该已经发现了,在本教程前几篇中的代码,还存在着bug,比如多点击几下之后图片会嗖的一下连着,或者点一下左边再点一下右边之后,图片会左右晃动一下等等……这些是由于每一次点击左滑或者右滑的时候,都会new一个计时器出来,然后几个计时器同时在操作当前的图片,自然就混乱了起来。解决方案很简单,让计时器变成一个公用的变量,并且让计时器在使用的用的过程中再去点击也无法调用。
    还有,当图片自动滑动的时候,再去点击一下,图片一会自动滑一会执行点击的滑动,这样的用户体验也不好,解决方案是,把鼠标悬停时候停止自动播放的范围扩大(相对前一篇教程),让用户的鼠标移动到左右滑动的肩头上就不再自动滑动了。
        现在,我们要改一下排版,将js外置。因为接下可能要书写的代码可能会比较长了。

    slider.js:
    function SliderClass(){
            // 计数
            var total = 0;
            var count = 0;
            // 前缀
            var pre = "list_";
            // 图片宽度
            this.width = 160;
            // 左中右对象
            this.pic_left=null;
            this.pic_center=null;
            this.pic_right=null;
            // 公用计时器
            this.timer = null;
            // 自动播放计时器
            this.autoplayTimer;
            
            // 初始化
            this.ini = function(){
    
            };
            
            // 获取操作对象
            this.getObject = function(){
               
            };
            
            // 左滑
            this.slideLeft = function(){
                
            };
            
            // 右滑
            this.slideRight = function(){
                
            };
            
            // 自动播放
            this.autoPlay = function(){
                
            };
        };
    

      

    如你所见,现在我们使用的是javascript面向对象的方式,构建一个SliderClass类,来专门处理这个滑动事件。

    首先,让我们来看一看ini()方法,事实上这个方法也可以说成是构造函数:
    // 初始化
            this.ini = function(){
                nameCount = 0;
                var last;
                var list = document.getElementById("list");
                list.style.width = this.width + "px";
                var temp = list.childNodes;
                for(var i=0;i<temp.length;i++){
                    if(temp[i].nodeName != "#text" && temp[i].nodeName == "LI"){
                        temp[i].id = "list_" + nameCount;
                        temp[i].style.width = this.width + "px";
                        temp[i].style.display = "none";
                        nameCount++;
                        last = i;
                    }
                }
                total = nameCount;
                count = total-1;
                temp[last].style.display = "";
    
                //绑定左右滑动
                var sliderclass= this;
                document.getElementById("left_arrow").onclick = function(){
                    sliderclass.slideLeft();
                };
                document.getElementById("right_arrow").onclick = function(){
                    sliderclass.slideRight();
                };
            };
    

      如果你是从教程开始几篇看过的来话,相信你对代码的前一部分一定不会陌生,不过后面绑定滑动这里或许会让你有些奇怪。其实这里这样调用的原因并不复杂,中间只是先用sliderclass这个临时变量来保存this(也就是SliderClass的当前对象),之所以这样做,是因为如果不这样的话,在绑定onclick方法以后,点击调用this,获取到的,将是你点击div的对象。

    // 获取操作对象
            this.getObject = function(){
                var left = pre+((count+total*100-1)%total);
                var center = pre+((count+total*100)%total);
                var right = pre+((count+total*100+1)%total);
                this.pic_left = document.getElementById(left);
                this.pic_center = document.getElementById(center);
                this.pic_right = document.getElementById(right);            
                this.pic_left.style.display = "";
                this.pic_right.style.display = "";
                this.pic_left.style.left = -this.width + "px";
                this.pic_center.style.left = 0 + "px";
                this.pic_right.style.left = this.width + "px";
            };
    

       这个方法没什么好说的,前几篇中已经出现好几次了,只不过这一次将它封装了起来。顺便说一句,里面拼装字符串的时候,通过count和total计算获取id的地方,博主本来想好好的算算的,不过最后嫌麻烦还是偷懒了,直接让count+total*100去%total,因为count到了负数的时候,计算id变得有点麻烦,所以就这样子算了,需要一提的时候,如果用户点了一百次向左的话,这个程序就会出现bug了,不过一般人应该不会这么无聊,如果你觉得浏览你的网站的人里面会有这么无聊的人的话,你也可以把乘的数设的大一点,比如一千或者一万

    // 左滑
            this.slideLeft = function(){
                // 获取对象
                this.getObject();
                // 若timer不会null,则表示计时器正在使用,未避免冲突此时return
                if(this.timer != null){
                    return;
                }
                var i=0;
                // 保存当前对象
                var sliderclass = this;
                this.timer = setInterval(function(){
                    if(i<=sliderclass.width){
                        sliderclass.pic_left.style.left = i-sliderclass.width + "px";
                        sliderclass.pic_center.style.left = i + "px";
                        sliderclass.pic_right.style.left = i+sliderclass.width + "px";
                        i+=sliderclass.width/4;
                    }else{
                        clearInterval(sliderclass.timer);
                        // 若滑动结束,则将计时器设为null
                        sliderclass.timer = null;
                    }
                },80);
                count--;            
            };
            
            // 右滑
            this.slideRight = function(){
                this.getObject();
                var i=this.width;
                if(this.timer != null){
                    return;
                }
                var sliderclass = this;
                this.timer = setInterval(function(){
                    if(i>=0){
                        sliderclass.pic_left.style.left = i - sliderclass.width*2 + "px";
                        sliderclass.pic_center.style.left = i - sliderclass.width + "px";
                        sliderclass.pic_right.style.left = i + "px";
                        i-=sliderclass.width/4;
                    }else{
                        clearInterval(sliderclass.timer);
                        sliderclass.timer = null;
                    }
                },80);
                count++;
            };
    

      左滑和右滑,这两个方法本身没有太大的改变,重点是使用了公用的计时器,并加上了判断,若计时器在使用(正在滑动)的话则不能调用(return),然后是将滑动的坐标根据图片宽度来联动生成。关于保存对象的原因上面已经说过,这里不做赘述了。

    // 自动播放
            this.autoPlay = function(){
                // 保存对象
                var sliderclass = this;
                // 鼠标悬停时停止自动播放
                document.getElementById("window").onmouseover = function(){
                    clearInterval(sliderclass.autoplayTimer);
                };
                // 鼠标离开后继续自动播放
                document.getElementById("window").onmouseout = function(){
                    sliderclass.autoPlay();
                };
                //  自动播放计时器
                this.autoplayTimer = setInterval(function(){
                    sliderclass.slideRight();
                },2000);
            };
    

      

     这里跟上一个版本几乎一样,只是把暂停自动播放的范围扩大了一些(相对上一个版本),这样就避免了客户跟自动播放互相抢着切换图片了。

    好了,下面是整个js的完整内容。

    slider.js:

    function SliderClass(){
            
            var total = 0;
            var count = 0;
            // 前缀
            var pre = "list_";
            // 图片宽度
            this.width = 160;
            // 左中右对象
            this.pic_left=null;
            this.pic_center=null;
            this.pic_right=null;
            // 计时器
            this.timer = null;
            this.autoplayTimer;
            
            // 初始化
            this.ini = function(){
                nameCount = 0;
                var last;
                var list = document.getElementById("list");
                list.style.width = this.width + "px";
                var temp = list.childNodes;
                for(var i=0;i<temp.length;i++){
                    if(temp[i].nodeName != "#text" && temp[i].nodeName == "LI"){
                        temp[i].id = "list_" + nameCount;
                        temp[i].style.width = this.width + "px";
                        temp[i].style.display = "none";
                        nameCount++;
                        last = i;
                    }
                }
                total = nameCount;
                count = total-1;
                temp[last].style.display = "";
                // 保存SliderClass当前的对象
                var sliderclass= this;
                //绑定左右滑动
                document.getElementById("left_arrow").onclick = function(){
                    // 如果上面不保存this对象的话,这里使用this关键字获取的将是你点击的div(id="left_arrow")
                    sliderclass.slideLeft();
                };
                document.getElementById("right_arrow").onclick = function(){
                    sliderclass.slideRight();
                };
            };
            
            // 获取操作对象
            this.getObject = function(){
                var left = pre+((count+total*100-1)%total);
                var center = pre+((count+total*100)%total);
                var right = pre+((count+total*100+1)%total);
                this.pic_left = document.getElementById(left);
                this.pic_center = document.getElementById(center);
                this.pic_right = document.getElementById(right);            
                this.pic_left.style.display = "";
                this.pic_right.style.display = "";
                this.pic_left.style.left = -this.width + "px";
                this.pic_center.style.left = 0 + "px";
                this.pic_right.style.left = this.width + "px";
            };
            
            // 左滑
            this.slideLeft = function(){
                // 获取对象
                this.getObject();
                // 若timer不会null,则表示计时器正在使用,未避免冲突此时return
                if(this.timer != null){
                    return;
                }
                var i=0;
                // 保存当前对象
                var sliderclass = this;
                this.timer = setInterval(function(){
                    if(i<=sliderclass.width){
                        sliderclass.pic_left.style.left = i-sliderclass.width + "px";
                        sliderclass.pic_center.style.left = i + "px";
                        sliderclass.pic_right.style.left = i+sliderclass.width + "px";
                        i+=sliderclass.width/4;
                    }else{
                        clearInterval(sliderclass.timer);
                        // 若滑动结束,则将计时器设为null
                        sliderclass.timer = null;
                    }
                },80);
                count--;            
            };
            
            // 右滑
            this.slideRight = function(){
                this.getObject();
                var i=this.width;
                if(this.timer != null){
                    return;
                }
                var sliderclass = this;
                this.timer = setInterval(function(){
                    if(i>=0){
                        sliderclass.pic_left.style.left = i - sliderclass.width*2 + "px";
                        sliderclass.pic_center.style.left = i - sliderclass.width + "px";
                        sliderclass.pic_right.style.left = i + "px";
                        i-=sliderclass.width/4;
                    }else{
                        clearInterval(sliderclass.timer);
                        sliderclass.timer = null;
                    }
                },80);
                count++;
            };
            
            // 自动播放
            this.autoPlay = function(){
                var sliderclass = this;
                document.getElementById("window").onmouseover = function(){
                    clearInterval(sliderclass.autoplayTimer);
                };
                document.getElementById("window").onmouseout = function(){
                    sliderclass.autoPlay();
                };
    this.autoplayTimer = setInterval(function(){
                    sliderclass.slideRight();
                },2000);
            };
        };
    

      页面index.html:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>js简单的滑动教程(四) - Lellansin</title>
    <script src="slider.js" type="text/javascript"></script>
    <style type="text/css">
        *{    margin:0; padding:0; }
        li{    list-style: none; }
        #window{ height:200px; 230px;    margin:0 auto; overflow:hidden; }
        #center_window{    height:200px; 160px; float:left; }
        #center_window ul{ height:200px; 160px; position:absolute; overflow:hidden; z-index: -1; }
        #center_window ul li{ height:200px; 160px; float:left; position:absolute; }
        #center_window img{ display:block; margin:5px auto; }
        #left_arrow{ height:200px; 35px; float:left; background:url("left.png") no-repeat scroll 5px 75px #fff; }
        #left_arrow:hover{ cursor: pointer; }
        #right_arrow{ height:200px;  35px; float:right; background:url("right.png") no-repeat scroll 0px 75px #fff; }
        #right_arrow:hover{ cursor: pointer; }
    </style>
    <script>
        window.onload = function(){
            var slider = new SliderClass();
            slider.ini();
            slider.autoPlay();
        }
    </script>
    </head>
    
    <body>
        <div id="window">
            <div id="left_arrow"></div>
            <div id="center_window">
                <ul id="list">
                    <li><img src="img/1.jpg" /></li>
                    <li><img src="img/2.jpg" /></li>
                    <li><img src="img/3.jpg" /></li>
                    <li><img src="img/1.jpg" /></li>
                    <li><img src="img/2.jpg" /></li>
                    <li><img src="img/3.jpg" /></li>
                </ul>
            </div>
            <div id="right_arrow"></div>
        </div>
    </body>
    </html>
    

      

  • 相关阅读:
    stm32f103串口实现映射功能
    Who is YaoGe.(搞笑篇)
    hdoj-2066-一个人的旅行(迪杰斯特拉)
    Webpack 性能优化 (一)(使用别名做重定向)
    How Visual Studio 2012 Avoids Prompts for Source
    HDU 4031 Attack
    js实现的省市联动
    Java几种单例模式的实现与利弊
    python项目实现配置统一管理的方法
    我的AI之路 —— OCR文字识别快速体验版
  • 原文地址:https://www.cnblogs.com/xiangxiong/p/6955291.html
Copyright © 2020-2023  润新知