JS实现图片无缝滚动效果

首先,借助一张草图来简单说明一下往左移动的做法(往右相同)。
JS实现图片无缝滚动效果_第1张图片
如上图所示,图片的无缝滚动原理其实是把滚动的图片复制成两份并联排列,当滚动完一次后就把图片扯回到起点,重新滚动。这里的往左运动把图片扯回起点的临界点是offsetLeft的绝对值大于offsetWidth/2的绝对值。

接着,我们再来看看具体实现的代码:
第一步:简单的布局,这里以外层的div为相对物设置相对定位并设置超出隐藏,再给里面的ul设置绝对定位,然后通过JS控制left和top的值来实现图片的移动。
要注意的是:无缝滚动图如果不设置margin和padding值为0会出现bug,图片衔接缺像素,两段图片移动完后会出现卡跳现象。新闻滚动如果不设置margin和padding为0,则会出现反向加速运动的bug。估计bug是因为所有元素间自动存在间隙,而设置的运动像素和内边距padding有关?会不会呢?谁知道。。。。


<html>
    <head>
        <meta charset="UTF-8">
        <title>title>
        <style type="text/css">
            *{margin: 0;padding: 0;}
            #box{width: 800px;height: 150px;margin: 100px auto;position: relative;background: red;overflow: hidden;}
            #box ul{position: absolute;left: 21px;top: 17px;}
            #box ul li{float: left;width: 190px;height: 150px;list-style: none;}
        style>
    head>
    <body>
        <a href="javascript:;">向左走a>
        <a href="javascript:;">向右走a>
        <div id="box">
            <ul>
                <li><img src="../img/images/a1.jpeg"/>li>
                <li><img src="../img/images/a2.jpeg"/>li>
                <li><img src="../img/images/a3.jpeg"/>li>
                <li><img src="../img/images/a4.jpeg"/>li>
            ul>
        div>
    body>
html>

第二步:根据标签名和ID名获取即将要用到的元素。这里也有一个隐藏的知识点:通过标签名获取元素,返回的是对象的集合(数组),[<p#pp.aa>,<p#ppp.aa>,<p#pppp.aa>],就是<标签名id名类名>这样的一个集合,后面加[0]返回的就是第一个对象,就像获取数组内的元素一样,如果不加[0]是就出现了错误。或者可以改成通过Id名获取元素,这样就返回的第一个对象,<p id="pp" class="aa"></p>是这样的,不过不返回文本内容

var oDiv=document.getElementById('box');

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

var aLi=oUl.getElementsByTagName('li');

第三步:把ul的内容加长到2倍,写一个函数,left值减去2px,先让函数执行一次,避免出现加载完页面后先出现停顿的现象,然后定义一个定时器,每30毫秒执行一次,实现图片滚动效果。

oUl.innerHTML+=oUl.innerHTML;

function move(){

    oUl.style.left=oUl.offsetLeft-2+'px';

}
//先执行一次函数
move();
//设置一个短时定时器,让图片运动看起来流畅
var timer=setInterval(move,30);

第四步:计算ul的总长度:获取一个li的宽度(不要单位)*li的数量+单位。然后写两个条件语句,判断滚动是否到达临界点,如果到达,就执行相对应的操作。

oUl.style.width=aLi[0].offsetWidth*aLi.length+'px';
function move(){
    //这里的移动,往左left为负,往右为正
    //往左的移动,判断ul的left值,如果小于负长度的一半,说明内容的第二段已经移动完,则left要归零重新移动
    if(oUl.offsetLeft<-oUl.offsetWidth/2){
        oUl.style.left='0';
    }
    //往右的移动,判断ul的left值,如果大于0,说明内容的第二段已经移动完,则left要回到负长度的一半重新移动,则left要重新设置为负长度的一半
    if(oUl.offsetLeft>0){
        oUl.style.left=-oUl.offsetWidth/2+'px';
    }
    oUl.style.left=oUl.offsetLeft-2+'px';
}

第五步:设置一个变量,赋值为每次滚动的像素,并且把常量2改为speed;如果变更滚动方向时,只需改变变量speed的符号即可。

var speed=2;

oUl.style.left=oUl.offsetLeft+speed+'px';

//鼠标点击事件,speed为负数,往左走
document.getElementsByTagName('a')[0].οnclick=function(){
    speed=-2;
}
//鼠标点击事件,speed为正数,往右走
document.getElementsByTagName('a')[1].οnclick=function(){
    speed=2;
}

第六步:最后加上两个鼠标事件,效果就OK啦。

//鼠标经过事件,关闭定时器,图片停止移动
oDiv.οnmοusemοve=function(){
    clearInterval(timer);
}
//鼠标离开事件,重新打开定时器
oDiv.οnmοuseοut=function(){
    timer=setInterval(move,30);
}

虽然已经是完成了这么一个效果,但是还有一些bug是没有解决的,等以后学了更加知识再慢慢修正吧。

你可能感兴趣的:(JS实现图片无缝滚动效果)