在网上浏览网页的时候,我们常常会看看无缝滚动的各种图片广告,但那是怎么实现的呢,今天我们就来说说如何实现图片的无缝滚动。
首先,我们来看看结构层,也就是html,大家把src替换成自己的图片,图片的大小不要求一样大,代码会自动调整图片的大小,使其铺满整个容器。
<ul id="marquee"> <li> <img id="index1" src="img/1.png" /> <img id="index2" src="img/2.png" /> <img id="index2" src="img/3.png" /> <img id="index2" src="img/4.png" /> <img id="index2" src="img/5.png" /> <img id="index2" src="img/6.png" /> </li> </ul>
总的思路基本是这样,让图片整体向某个方向移动,当图片移动到某一个距离后就回到原点。为了防止图片移着移着就没有了,我们需要两套相同的图片。
首先大家肯定有个疑惑,图片大小不一致真的可以吗?可以,大家只需要用css设置父容器的大小就可以了,剩下的交给代码解决。我们先用window.getComputedStyle来获取父容器的大小,这里获取的数值是有px的,因此还需要切除,前面的“+”是将其转化为数值。
//获取容器设定的宽度,用于设定img的宽度,使得图片自适应容器的大小。 cWidth=window.getComputedStyle(container , null)['width']; cHeight=window.getComputedStyle(container , null)['height']; cWidth=+cWidth.slice(0,cWidth.length-2); cHeight=+cHeight.slice(0,cHeight.length-2);
但是大家都知道img有个问题,就是他们之间并不是无缝的,为此,我用style.cssText将img设置为float:left;这样,图片之间就是无缝的了,也就是默认状态下图片是水平排列的。那如果我要向上或者向下滚动呢,只需要设置li的宽度为父容器的宽度就可以变成竖直排列了,是不是很简单?前面我还提到图片的大小
//设置图片的样式,float:left;所以不管在什么情况下,图片与图片之间都是无缝连接的,后面只需要改动slide宽度,就可以改变图片的排列方式了,水平竖直无缝切换 for(var i=0 ,l=img.length; i<l;i++){ img[i].style.cssText = "float:left;"+cWidth+"px;height:"+cHeight+"px"; } //将宽度变为两倍这样可以容下两倍的图片,即默认是水平排列,同时复制一份自身加到原来图像上 slide.style.width=imgNum*2*cWidth+"px"; slide.innerHTML += slide.innerHTML;
那该滚动到什么时候,我们是不是应该设置一个临界点?是的,我们必须设置一个临界点,当所有的图片都过了一遍的时候,我们就把它拉回来重新开始滚,因为方向的不同,临界点自然也不一样,跟父容器的大小有关。
//水平和竖直方向上的临界点 var horizontal = slide.offsetWidth/2, vertical=imgNum*cHeight;
准备工作做好之后,就可以开始写滚动函数了。不管是哪个方向的滚动,其实原理是差不多的。下面就以向上滚动为例来讲讲。
因为图片默认是水平排列的,因此第一步就是让图片数值排列。只要改变li的大小就可以了。我们在设一个变量,用来滚动,当滚动到临界点的时候,就重新开始滚动。方向向上,临界点就是当滚动的距离是所有的图片高度之和的时候,这时候,就可以返回了。代码具体如下:
//slide.style.width是要有px的,而img[0].width是没有px的,只是数值 slide.style.width=img[0].width+"px";//这样图片只能竖着排列 //console.log(img[0].width); //500 var delta=0; var rolling = function(){ delta == -vertical ? delta = 0 : delta--; slide.style.top = delta + "px"; }
其他方向类推就是了。有四个放下,我们采用swich语句来实现方向的选择。
当然,有时候,有些人对图片上的东西感兴趣,这时候,我们可以设置鼠标hover的时候,就暂停,移出去就继续滚动。
container.onmouseover=function() {clearInterval(timer)}//鼠标移到marquee上时,清除定时器,停止滚动 container.onmouseout=function() {timer=setInterval(rolling,speed)}//鼠标移开时重设定时器
最后附上源码供大家学习参考:
<!doctype html> <html> <head> <title>图片的无缝滚动 by sjq</title> <meta charset="utf-8"/> <style type="text/css"> h1 { font:400 16px/1 "Microsoft YaHei",KaiTi_GB2312,SimSun } #marquee { width: 500px; height: 400px; padding:0; margin:0; overflow: hidden; } #marquee { position:relative; list-style:none; border:10px solid #369; } #marquee li { position:absolute; margin: 0px; padding: 0px; } #marquee img{ margin: 0px; padding: 0px; } </style> </head> <body> <h1>图片的无缝滚动 by sjq</h1> <ul id="marquee"> <li> <img id="index1" src="img/1.png" /> <img id="index2" src="img/2.png" /> <img id="index2" src="img/3.png" /> <img id="index2" src="img/4.png" /> <img id="index2" src="img/5.png" /> <img id="index2" src="img/6.png" /> </li> </ul> </body> <script type="text/javascript"> var Marquee = function(id,direction,speed){ //为了防止在ie6及以下的浏览器出现图片一闪的现象 try{document.execCommand("BackgroundImageCache", false, true);}catch(e){}; var container = document.getElementById(id), slide = container.getElementsByTagName("li")[0], img= container.getElementsByTagName("img"), speed = parseInt(speed)|| 10,//默认速度为10 imgNum=img.length; //获取图片的数量 //获取容器设定的宽度,用于设定img的宽度,使得图片自适应容器的大小。 cWidth=window.getComputedStyle(container , null)['width']; cHeight=window.getComputedStyle(container , null)['height']; cWidth=+cWidth.slice(0,cWidth.length-2); cHeight=+cHeight.slice(0,cHeight.length-2); //设置图片的样式,float:left;所以不管在什么情况下,图片与图片之间都是无缝连接的,后面只需要改动slide宽度,就可以改变图片的排列方式了,水平竖直无缝切换 for(var i=0 ,l=img.length; i<l;i++){ img[i].style.cssText = "float:left;"+cWidth+"px;height:"+cHeight+"px"; } //console.log(container.getElementsByTagName("li")[0].offsetHeight);//400 //console.log(container.getElementsByTagName("img")[0].offsetHeight);//400 //console.log("container.scrollTop"+container.scrollTop);//0 //将宽度变为两倍这样可以容下两倍的图片,即默认是水平排列,同时复制一份自身加到原来图像上 slide.style.width=imgNum*2*cWidth+"px"; slide.innerHTML += slide.innerHTML; //水平和竖直方向上的临界点 var horizontal = slide.offsetWidth/2, vertical=imgNum*cHeight; console.log("slide.offsetWidth:"+slide.offsetWidth); //console.log(container.getElementsByTagName("li")[0].offsetHeight);//400 //console.log("img[0].height"+img[0].height);//400 //根据方向选取不同运动方式 switch(direction){ //刚开始距离左边为0 case "left": var delta = 0; var rolling = function(){ delta == -horizontal ? delta = 0 : delta--; slide.style.left = delta + "px"; } break; //刚开始定位到复制的那一份的位置,然后在滚动,滚动到头的时候,再切换回去 case "right": var delta=-horizontal; var rolling = function(){ delta == 0 ? delta = -horizontal : delta++; slide.style.left = delta + "px"; } break; //刚开始距离上边为0 case "up": //slide.style.width是要有px的,而img[0].width是没有px的,只是数值 slide.style.width=img[0].width+"px";//这样图片只能竖着排列 //console.log(img[0].width); //500 var delta=0; var rolling = function(){ delta == -vertical ? delta = 0 : delta--; slide.style.top = delta + "px"; } break; case "down": slide.style.width=img[0].width+"px";; var delta=-vertical; var rolling = function(){ delta == 0 ? delta = -vertical : delta++; slide.style.top = delta + "px"; } break; } var timer = setInterval(rolling,speed)//设置定时器 container.onmouseover=function() {clearInterval(timer)}//鼠标移到marquee上时,清除定时器,停止滚动 container.onmouseout=function() {timer=setInterval(rolling,speed)}//鼠标移开时重设定时器 } window.onload = function(){ Marquee("marquee","up","ttt"); } </script> </html>
ps:最后大家实现临界点哪里也可以采用scrollTop,scrollLeft,offsetWidth来实现
本文参考: