在网上浏览网页的时候,我们常常会看看无缝滚动的各种图片广告,但那是怎么实现的呢,今天我们就来说说如何实现图片的无缝滚动。
首先,我们来看看结构层,也就是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;width:"+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;width:"+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>
View Code
ps:最后大家实现临界点哪里也可以采用scrollTop,scrollLeft,offsetWidth来实现
树林美丽、幽暗而深邃,但我有诺言尚待实现,还要奔行百里方可沉睡。 -- 罗伯特·弗罗斯特