无缝滚动--基本实现

来源:互联网 发布:弦月梦影淘宝 编辑:程序博客网 时间:2024/05/16 14:06

      工作一年多了,终于是从c++转java 了,虽然能够完成平时的工作,但是 总是感觉自己的js基础知识不太扎实,很多地方都是拿来就用,虽然实现了想要的

效果,但是其实都不知道为什么,我想总是用拿来主义,这样肯定不能提高自己,加上近来工作不是很忙,就想开始好好的学习掌握一下js基础,这篇博文就是昨天学习的成果,现在总结一下,也希望科以帮到正在探索js的童鞋。

     在实现无缝滚动之前,我们先举一个简单的例子,先来实现让一个div运动

 1、body部分

      <button  id="Btn1">向右移动</button>      <button  id="Btn2">停止移动</button>      <!-- 要想让一个div运动必须添加:position:absolute -->      <div id="div1"></div>
2、样式

 #div1{width:200px;height:80px;background:#ccc;margin-top:10px;position:absolute;left:0px;}

3、js部分

<script type="text/javascript"> window.onload=function(){  var oDiv1 = document.getElementById("div1"); var oBtn = document.getElementById("Btn1"); var oBtn2 = document.getElementById("Btn2"); var timer = null; //向右移动 oBtn.onclick = function(){ //打开定时器 timer = setInterval(function(){ //要让div向右移动就需要改变div的left的值, //有人可能想用用到 oDiv1.style.left = oDiv1.style.left + 移动长度  ,但是是不可行的 //因为我们拆开来看就是:oDiv1.style.left ="0px" + 10  => '0px10',这个电脑肯定不能识别 //所以我们需要用到 :offsetLeft  这个是一个具体的数值  oDiv1.offsetLeft就表示当前位置 oDiv1.style.left = oDiv1.offsetLeft + 2 +"px"; },30); }//停止移动 oBtn2.onclick = function(){//关闭定时器 clearTimeout(timer); }    }  </script>

按照上面的例子,我们可以让一个div向右移动,我们主要需要掌握的我在上面的js中都通过注释的方式写出来了,一个是:offsetLeft的作用,
一个是:定时器让物体连续移动,上面介绍的东西虽然看起来很简单,很低俗,但是掌握了上面用到的知识,足够让我们来实现一个无缝滚动了,

好了,接下来我们切入正题,实现无缝滚动。

一、html代码如下:

 <div class="roll" id="roll">      <a href="javascript:void(0);" class = "btn_left" ></a>      <a href="javascript:void(0);" class = "btn_right" ></a>      <div class="marquee">        <ul>            <li><a href="#"><img src="01.jpg"/><em>jquery 特效</em></a></li>            <li><a href="#"><img src="02.jpg"/><em>滚动代码</em></a></li>            <li><a href="#"><img src="03.jpg"/><em>导航菜单</em></a></li>            <li><a href="#"><img src="04.jpg"/><em>兼职网站大全</em></a></li>            </ul>          </div>   </div>   


二、css样式如下:

<style>.roll { width: 780px; height: 108px; margin: 50px auto 0; position: relative; } .btn_left { display: block; width: 100px; height: 100px; background: url(5.png) ; position: absolute; top: 20px; left: 1px; z-index: 1; }  .btn_right { display: block; width: 120px; height: 120px; background: url(6.png); position: absolute; top: 20px; right: 0; z-index: 1; }  a{ font-size:13px; color:#333333; text-decoration:none;}a:hover{color:red; text-decoration:underline;}img{ border:none;}.roll .marquee {width:600px;height:260px;overflow:hidden;-border:1px solid #333;left:110px; margin-top:20px;position:relative;}.marquee ul{ position : absolute;left:0px;}.marquee li{ display:inline; float:left; -margin-right:12px;}.marquee li a{ width:200px; height:250px; display:block; float:left; text-align:center; font-size:14px;}.marquee li a:hove{ text-decoration:none;}.marquee li img {width:140px; height:140px;}.marquee li em{font-style: normal; height:24px; line-height:24px; display:block; margin-top:8px;}.marquee button{position:absolute; top:50%; height:24px;}   </style> 


第三步:js实现部分

31.通过上面的小例子,我们首先可以让图片动起来

window.onload=function(){ //1、获取最外层的div  var oDiv = document.getElementById("roll"); //2、通过div获取它下面唯一的一个 ul var oUl = oDiv.getElementsByTagName("ul")[0]; //3、开启一个定时器:让ul的left值不断变小,向左运动  setInterval(function(){ oUl.style.left = oUl.offsetLeft - 5 +'px'; },300);  }
上面三步,运行起来就实现了左移动,但是现在有一个布局上的问题:效果图如下


为了帮助大家看的清楚,我们将
        .marquee 的css样式:加上 边框border:1px solid #333;去掉overflow:hidden;

可以发现图片折行了,因为ul没有宽度,所以最后一张图片就会被相对比较窄的div(就是有黑色边框的)挤下去了,

所以我们要让ul有一个足够大的宽度,那么ul要设置为多少比较合理呢?

其实一般来说ul的宽度就是每个li的宽度的总和,而每个li的宽度都是相同的

所以ul的宽度就是: li的个数* 每个li的宽度, 等价于     oLi[0].offsetWidth * oLi.length  设置了ul的宽度,那四个li就拥有了足够的宽度,

就能在一行显示,好了我们在上面代码的基础上,设置一下ul的宽度,修改代码如下:

 window.onload=function(){ //1、获取最外层的div  var oDiv = document.getElementById("roll"); //2、通过div获取它下面唯一的一个 ul var oUl = oDiv.getElementsByTagName("ul")[0];//3、设置ul的宽度    //3.1  获取 ul下所有的li    var oLi = document.getElementsByTagName("li");    //3.2  通过js动态设置ul的宽度    oUl.style.width = oLi[0].offsetWidth * oLi.length+"px";    //4、开启一个定时器:让ul的left值不断变小,向左运动 ,这是所有图片都在一行上面 setInterval(function(){ oUl.style.left = oUl.offsetLeft - 5 +'px'; },300);    }
在运行效果图如下:



这时我们发现图片就在一行上面了,达到了我们想要的效果,可是现在图片移动一直在向左运动之后,出现了空白的部分,这就是没有实现无缝,

那怎么办呢,不用着急,一般来说遇到这个问题我们的解决办法是:

首先:将lu下面的每个li复制一份,这个我们可以用 innerHTML来实现

oUl.innerHTML = oUl.innerHTML +  oUl.innerHTML    但是复制了之后,还是会出现空白

然后: 我们还需要在ul的左边距小于ul宽度一般的时候,将ul的left值变为opx,为什么要这样做,我们下面详细说一说

为了帮助大家理解,我画了下面的模拟效果图


给大家介绍一下:
这个图里面的编号为1、2、3、4的四个矩形框就代表着正在向左移动的四张图片,有两份相同编号的是因为 后面的一份是前面的复制出来的,
实际上用户所能看见的就只有上面黑色实线框那么宽,1、2、3、4一直在向左移动,知道移动到现在效果图显示的位置,我们发现最开始用户看见的是1、2、3
现在图上用户又要看见1、2、3了,这个时候整个东西在用户眼里又回到了最开始看见的相同的状态,我在这个时候用一个障眼法,把前面的1、2、3、4
一瞬间在拉回去,就这样重复,实际上用户是看不出来你把它往回拉的,我们什么时候往会拉呢?其实看图就能发现,如果假设八张图片的宽度是8,
当图片滚到一半的时候,就是第四张图片正好在div外面的时候,我们就可以把它拉回来,实际上我们就可以理解为:
在js中检测当ul的左边距小于ul宽度一半的时候拉回来,
那怎么实现往回拉的效果呢,这个就简单了,直接将ul的left值重新设置为0p就可以了噢,好啦,不知道大家听懂了没有,如果没懂就自己动手画画图,好
好想一想li的运动过程,理解了上面这些,我们就继续修改js吧

window.onload=function(){ //1、获取最外层的div  var oDiv = document.getElementById("roll"); //2、通过div获取它下面唯一的一个 ul var oUl = oDiv.getElementsByTagName("ul")[0];                //3、 实现复制一份lu下面的li oUl.innerHTML += oUl.innerHTML;         //4、设置ul的宽度    //4.1  获取 ul下所有的li    var oLi = document.getElementsByTagName("li");    //4.2  通过js动态设置ul的宽度    oUl.style.width = oLi[0].offsetWidth * oLi.length+"px";    //5、开启一个定时器:让ul的left值不断变小,向左运动 ,这是所有图片都在一行上面 setInterval(function(){ oUl.style.left = oUl.offsetLeft - 5 +'px'; //6、检测往回拉的时间,因为是在向左移动所以 oUl.offsetLeft为负数 if(oUl.offsetLeft < -oUl.offsetWidth/2){//7、当ul的左边距小于 ul宽度的一半的时候,就拉回来 oUl.style.left = "0px"; } },300);

至此:基本实现了无缝滚动,效果图如下:



接下来我们在来实现无缝滚动的两个扩张功能:

1、图上还有两个按钮,我们需要实现按钮来控制图片移动的方向

 oUl.style.left = oUl.offsetLeft +speed+'px';这句代码表示我们每次给ul的left加上去了一个speed(速度),

如果speed是个负数,那么ul的left的值越来越小,这时候图片是在向左移动

如果speed是个正数,那么当ul的left的值越来越大,这时图片实在向右运动

那么要实现这个功能就很简单了,只用定义一个speed表示图片移动的速度,

当向左运动的时候speed变成一个负数

当向右运动的时候speed变成一个正数就可以了

代码如下:

<script type="text/javascript"> window.onload=function(){ //1、获取最外层的div  var oDiv = document.getElementById("roll"); //2、通过div获取它下面唯一的一个 ul var oUl = oDiv.getElementsByTagName("ul")[0];  //3、获取左箭头  var oBtn1=oDiv.getElementsByTagName('a')[0];      //4、获取右箭头  var oBtn2=oDiv.getElementsByTagName('a')[1];   //5、定义移动速度 var speed = -5;           //6、 实现复制一份lu下面的li oUl.innerHTML += oUl.innerHTML;                           //7、设置ul的宽度    //7.1  获取 ul下所有的li    var oLi = document.getElementsByTagName("li");    //7.2  通过js动态设置ul的宽度    oUl.style.width = oLi[0].offsetWidth * oLi.length+"px";          //8、开启一个定时器:让ul的left值不断变小,向左运动 ,这是所有图片都在一行上面 setInterval(function(){ oUl.style.left = oUl.offsetLeft + speed +'px'; //6、检测往回拉的时间,因为是在向左移动所以 oUl.offsetLeft为负数 if(oUl.offsetLeft < -oUl.offsetWidth/2){//7、当ul的左边距小于 ul宽度的一半的时候,就拉回来 oUl.style.left = "0px"; }//11、当向右运动的时候,右变出现空白,检测当ul的left的值大于0的时候拉回if(oUl.offsetLeft > 0){//7、设置拉回的长度:拉回到自身宽度的一半 oUl.style.left = -oUl.offsetWidth/2;} },300);         //9、给向左移动添加鼠标移入的事件,修改速度为正数,向左走      oBtn1.onmouseover = function(){      speed = -5;       }   //10、给向左移动添加鼠标移入的事件,修改速度为正数,向左走      oBtn2.onmouseover = function(){      speed = 5;      }    }
至此我们做完了这个扩展功能,总结一下总共做了两件事:

1、修改移动速度:speed  因为speed为正或者为负直接决定了图片向左滚动还是向右滚动

2、修改判断条件,因为之前我们考虑了往左走走到一半的时候把它拉回来,而现在我们要多考虑一个向又走的情况

第二个扩展:鼠标移入暂停功能

一般的无缝滚动都有一个特点:当鼠标移入到图片的额时候会暂停,鼠标移出的时候继续滚动

这个就很简单了,只需要在:

鼠标移入的时候关闭定时器

鼠标移出的时候重新开启定时器


最后完整js代码如下:

 window.onload=function(){ //1、获取最外层的div  var oDiv = document.getElementById("roll"); //2、通过div获取它下面唯一的一个 ul var oUl = oDiv.getElementsByTagName("ul")[0];  //3、获取左箭头  var oBtn1=oDiv.getElementsByTagName('a')[0];      //4、获取右箭头  var oBtn2=oDiv.getElementsByTagName('a')[1];   //5、定义移动速度 var speed = -5;  //11、定义定时器变量 var timer = null;         //6、 实现复制一份lu下面的li oUl.innerHTML += oUl.innerHTML;//7、设置ul的宽度    //7.1  获取 ul下所有的li    var oLi = document.getElementsByTagName("li");    //7.2  通过js动态设置ul的宽度    oUl.style.width = oLi[0].offsetWidth * oLi.length+"px";    //8、开启一个定时器:让ul的left值不断变小,向左运动 ,这是所有图片都在一行上面 timer = setInterval(function(){ oUl.style.left = oUl.offsetLeft + speed +'px'; //6、检测往回拉的时间,因为是在向左移动所以 oUl.offsetLeft为负数 if(oUl.offsetLeft < -oUl.offsetWidth/2){//7、当ul的左边距小于 ul宽度的一半的时候,就拉回来 oUl.style.left = "0px"; } if(oUl.offsetLeft > 0){//7、当ul的左边距小于 ul宽度的一半的时候,就拉回来 oUl.style.left = -oUl.offsetWidth/2;} },200); //9、给向左移动添加鼠标移入的事件,修改速度为正数,向左走      oBtn1.onmouseover = function(){      speed = -5;       }   //10、给向左移动添加鼠标移入的事件,修改速度为正数,向左走      oBtn2.onmouseover = function(){      speed = 5;      }    //12、  鼠标移入的时候关闭定时器      oUl.onmouseover =function(){      clearInterval(timer);        }    //13、 鼠标移出的时候重新开启定时器      oUl.onmouseout =function(){      timer = setInterval(function(){ oUl.style.left = oUl.offsetLeft + speed +'px'; //6、检测往回拉的时间,因为是在向左移动所以 oUl.offsetLeft为负数 if(oUl.offsetLeft < -oUl.offsetWidth/2){//7、当ul的左边距小于 ul宽度的一半的时候,就拉回来 oUl.style.left = "0px"; } if(oUl.offsetLeft > 0){//7、当ul的左边距小于 ul宽度的一半的时候,就拉回来 oUl.style.left = -oUl.offsetWidth/2;} },200);      }    }







0 0