用js实现图片无缝滚动功能及其操控


一、滚动原理

无缝滚动就如字面意思,滚动过程中不出现空白,始终都是有内容在展示。这里用js实现图片的无缝滚动,原理就是设定一个盒子将内容图片包着作为展示框架,还没轮到展示的图片隐藏在盒子外面。为了防止出现空白和内容循环滚动,当最后一张图片的边缘快要进入盒子展示区时,把整个图片组的头部即第一张图片,调到出现空白的边缘位置,开始新一轮的循环滚动。而根据展示区盒子的大小,可以适当重复加长图片组的长度,这是防止在滚动前就出现空白的现象。


二、实例操作

四张图片默认循环向上滚动,有四个按钮可以控制,分别为向上滚动、向下滚动、停止滚动、继续滚动。

jquery marquee水平无缝滚动 js图片无缝滚动的原理_自定义

内容部分:

取四张宽高一样的图片,用列表的方式排列


<body>
	<div id="box">
		<ul>
			<li><img src="img/a1.jpeg"></li>
			<li><img src="img/a2.jpeg"></li>
			<li><img src="img/a3.jpeg"></li>
			<li><img src="img/a4.jpeg"></li>				
		</ul>
	</div>
	<p id="up">UP</p>
	<p id="down">DOWN</p>
	<p id="stop">STOP</p>
	<p id="continue">CONTINUE</p>
</body>



样式:


<style>
			* {
				margin: 0;
				padding: 0;
				list-style: none;
			}
			
			#box {
				width: 185px;
				height: 456px;
				border: 1px solid #888888;
				position: relative;
				overflow: hidden;
				margin: 30px;
			}
			
			#box ul {
				position: absolute;
				top: 0;
				left: 0;
			}
			
			#box ul li img {
				display: block;
				width: 185px;
				height: 116px;
			}
									
			p {
				width: 100px;
				height: 30px;
				line-height: 30px;
				background: gold;
				color: red;
				float: left;
				margin: 50px 10px;
				text-align: center;
			}
		</style>



接下来进行js部分的编写:

先给各个部分命名


var oBox = document.getElementById('box');
				var oUl = oBox.getElementsByTagName('ul')[0];
				var aLi = oUl.getElementsByTagName('li');
				var oUp = document.getElementById('up');
				var oDown = document.getElementById('down');
				var oStop = document.getElementById('stop');
				var oContinue=document.getElementById('continue');



这里oUl后面的[0]指的是ul下面的第一个li

var oUl = oBox.getElementsByTagName('ul')[0];



由于展示盒子的长度与整组图片长度一致,所以为了防止一开始滚动边缘即出现空白,在整组图片的后面添加相同的图片内容,即滚动两组图片为一轮。


oUl.innerHTML = oUl.innerHTML + oUl.innerHTML;


对oUl的高度赋值:


oUl.style.height = aLi[0].offsetHeight * aLi.length  + 'px';



这里aLi[0]即为第一个li,若上面的oUl命名后面没有加上[0]则无法识别。

然后进行第一轮滚动后的边缘位置处理。

向上滚动情况:

jquery marquee水平无缝滚动 js图片无缝滚动的原理_自定义_02

灰色部分为展示区,蓝色部分为两组图片。因为在样式里ul用了定位,所以对于是否处于边缘位置,用oUl的top值来判断。向上滚动时,初始图片的顶部与盒子顶部重合,top值为0,在向上滚动过程中,top值一直为负数,当图片底端与盒子底端重合时,即处于边缘位置,此时top值为整个oUl长度的一半,为了防止出现空白,把图片的位置调回初始状态,进行下一轮的滚动,所以把top值设为0.


向下滚动情况:

jquery marquee水平无缝滚动 js图片无缝滚动的原理_赋值_03

向下滚动时,开始位置相同,不过此时就处在边缘位置,滚动即在上部出现空白。因此,把顶部调到整个oUl的一半位置。

代码如下:


function move() {
					if (-oUl.offsetTop > oUl.offsetHeight / 2) {
						oUl.style.top = '0px';
					}
					if (oUl.offsetTop > 0) {
						oUl.style.top = -oUl.offsetHeight / 2 + 'px';
					}
					oUl.style.top = oUl.offsetTop + speed + 'px';
				}

这里用到一个speed值,是为了方便在设定向下向上滚动按钮,所以应该在前面先给speed赋值:


var speed=-2;


设置一个定时器,即每隔某个时间运行上面自定义的move()这个函数,进行不断滚动:


timer = setInterval(move, 100);


改变滚动的方向很简单,只需要改变speed值的正负,即top值的正负,正值为向下,负值为向上:


oUp.onclick = function() {
					speed = -2;					
				}
				oDown.onclick = function() {
					speed = 2;					
				}



停止按钮的设置:


oStop.onclick = function() {
					clearInterval(timer)
				}



继续按钮的设置:


oContinue.οnclick=function(){
					clearInterval(timer);
					timer = setInterval(move, 100);						
				}



在继续按钮的设置上,运行定时器滚动前必须先执行一次关闭定时器,否则多次点击“继续”会造成定时器的叠加,滚动速度越来越快。


到此,四张相同图片无缝滚动的例子已分析完毕,另外,如果想在后面多加一张宽度和高度都不相同的图片(图片也是放在ul下的li里面),则可先将该图片的宽度设置跟前面的图片相同,对于定比例改变后的高度与前面单张图片的高度作对比,多出来或减少的高度,这里先命名为value,则需要在oUl长度的计算中加上value*2的数值,多则为正数,少为负数。


oUl.style.height = aLi[0].offsetHeight * aLi.length  + value*2 +  'px';


整个代码如下图:

jquery marquee水平无缝滚动 js图片无缝滚动的原理_自定义_04