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; width:230px; margin:0 auto; overflow:hidden; }
#center_window{ height:200px; width:160px; float:left; }
#center_window ul{ height:200px; width:160px; position:absolute; overflow:hidden; z-index: -1; }
#center_window ul li{ height:200px; width:160px; float:left; position:absolute; }
#center_window img{ display:block; margin:5px auto; }
#left_arrow{ height:200px; width:35px; float:left; background:url("left.png") no-repeat scroll 5px 75px #fff; }
#left_arrow:hover{ cursor: pointer; }
#right_arrow{ height:200px; width: 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>

  

js 简单的滑动4的更多相关文章

  1. js 简单的滑动3

    js 简单的滑动教程(三)   作者:Lellansin 转载请标明出处,谢谢 在前面的基础上(js 简单的滑动教程(二)),我们可以再添加一些功能使程序的可用性更高. 比如自动为图片的LI赋id值, ...

  2. js 简单的滑动2

    js 简单的滑动教程(二)   作者:Lellansin 转载请标明出处,谢谢 现在我们让滑动多一个功能,三张图.点击左边向左滑动,点右向右滑,碰到临界值的时候可以循环滑动 原理也很将简单,用posi ...

  3. js 简单的滑动1

    js 简单的滑动教程(一)   作者:Lellansin 转载请标明出处,谢谢 首先我们要实现一个简单的滑动,三张图.点击左边向左滑动,点右向右滑,碰到临界值的时候就不能滑动. 这个简单滑动的原理是, ...

  4. js实现图片滑动显示效果

    js实现图片滑动显示效果 今天用户提出一个需求,要实现一个滑动显示新闻列表的效果,具体就是图片新闻自动滑动显示,鼠标移上去就停止滑动,移开就继续滑动:效果如下: 第一:先用HTML和CSS实现显示,主 ...

  5. baguetteBox.js - 简单易用的 lightbox 插件

    baguetteBox.js 是一个简单和易于使用的响应式的图像 Lightbox 插件,支持滑动手势在移动设备上使用.纯 JavaScript 实现,不依赖第三方库和插件,赶紧来体验吧. 在线演示  ...

  6. js简单 图片版时钟,带翻转效果

    js简单 图片版时钟,带翻转效果 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...

  7. js简单操作Cookie

    贴一段js简单操作Cookie的代码: //获取指定名称的cookie的值 function getCookie(objName) { var arrStr = document.cookie.spl ...

  8. js简单弹出层、遮罩层

    <html> <head> <title>js简单弹出层</title> <style> /*阴影边框效果*/ .box-shadow-1 ...

  9. Tourist.js – 简单灵活的操作指南和导航插件

    Tourist.js 是一个基于 Backbone 和 jQuery 开发的轻量库,帮助你在应用程序创建简单易用的操作指南和导航功能.相比网站,它更适合用于复杂的,单页网站类型的应用程序.Touris ...

随机推荐

  1. 大名鼎鼎的RPC和MQ到底有啥区别和联系

    RPC(Remote Procedure Call)远程过程调用,主要解决远程通信间的问题,不需要了解底层网络的通信机制. RPC框架 知名度较高的有Thrift(FB的).dubbo(阿里的). R ...

  2. 第06组 Beta冲刺(2/4)

    队名:福大帮 组长博客链接:https://www.cnblogs.com/mhq-mhq/p/11990570.html 作业博客 : https://edu.cnblogs.com/campus/ ...

  3. 中标麒麟(龙芯CPU)--忘记root密码怎么修改?

    中标麒麟桌面版和服务器版均采用GRUB2为启动器,无法通过单用户模式重置root密码.下面将介绍如何重置中标麒麟系统的root密码: 桌面版 1.修改grub2引导 在正常系统入口上按下"e ...

  4. 必须要注意的 C++ 动态内存资源管理(六)——vector的简单实现

    必须要注意的 C++ 动态内存资源管理(六)——vector的简单实现 十六.myVector分析         我们知道,vector类将其元素存放在连续的内存中.为了获得可接受的性能,vetor ...

  5. 【docker】 yaml.scanner.ScannerError: mapping values are not allowed here in "./docker-compose.yml", line 60, column 35

    在启动docker-compose 时候 报错了 命令: docker-compose up -d && docker-compose logs -f 错误代码: 解决 出现这个错误的 ...

  6. Qt编写图片及视频TCP/UDP网络传输

    一.前言 很多年前就做过类似的项目,无非就是将本地的图片上传到服务器,就这么简单,其实用http的post上传比较简单容易,无需自定义协议,直接设置好二进制数据即可,而采用TCP或者UDP通信的话,必 ...

  7. [LeetCode] 689. Maximum Sum of 3 Non-Overlapping Subarrays 三个非重叠子数组的最大和

    In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum. E ...

  8. 【Python学习之三】流程控制语句

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 一.条件分支if <条件判断1>: & ...

  9. Github首次使用教程(本地新建项目并同步到Github远程仓库)

    网上关于Github的教程很多且有点乱,自己亲自躺坑实践,现分享出来给将要入坑的小伙伴. 主要步骤: 创建Github帐号,登录,新建仓库(远程仓库) 下载安装Git,git bash配置及简单使用( ...

  10. Java 8 集合之流式(Streams)操作, Streams API 详解

    因为当时公司的业务需要对集合进行各种各样的业务逻辑操作,为了提高性能,就用到了这个东西,因为以往我们以前用集合都是需要去遍历(串行),所以效率和性能都不是特别的好,而Streams就可以使用并行的方式 ...