zoukankan      html  css  js  c++  java
  • 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>
    

      

  • 相关阅读:
    Java程序:从命令行接收多个数字,求和并输出结果
    大道至简读后感
    大道至简第一章读后感Java伪代码
    Creating a SharePoint BCS .NET Connectivity Assembly to Crawl RSS Data in Visual Studio 2010
    声明式验证超时问题
    Error message when you try to modify or to delete an alternate access mapping in Windows SharePoint Services 3.0: "An update conflict has occurred, and you must re-try this action"
    Upgrading or Redeploying SharePoint 2010 Workflows
    Upgrade custom workflow in SharePoint
    SharePoint 2013中Office Web Apps的一次排错
    How to upgrade workflow assembly in MOSS 2007
  • 原文地址:https://www.cnblogs.com/xiangxiong/p/6955291.html
Copyright © 2011-2022 走看看