【JavaScript从入门到精通】第十课 定时器的使用-02

此内容来自开课吧石川微信公众号

这节课让我们来一起做一个常见的网页效果——无缝滚动。

在制作无缝滚动前,我们需要解决的最基础的问题是——要如何让一个页面上的物体动起来?JS有很多复杂的运动,我们今天要做的是通过我们前面所学的基础知识来制作一些运动效果。

实际上,让一个元素动起来,我们目前能想到的最简单的方法就是修改一个元素的位置,在JS里我们通过定时器让元素定位的值(例如)不断变化,这样就实现了运动的效果。

在这里,我们先介绍一个属性:offsetLeft,用于获取元素的左边值(返回类型为数值型):

<html>
<head>
    <meta charset="utf-8"/>
    <title>无标题文档</title>
</head>
<body>
    <div id="div1" onclick="alert(this.offsetLeft);"></div>
</body>
</html>
#div1 {
    width: 200px;
    height: 200px;
    background: red;
    position: absolute;
    left: 200px;
    top: 150px;
    margin: 50px;
}

效果如下:

【JavaScript从入门到精通】第十课  定时器的使用-02

offsetLeft的最大优点在于可以综合考虑所有影响物体位置的因素,在这个例子里如果我们仅仅只取元素的left属性那么margin对元素位置的影响将被忽略掉。当然,相对的,也有offsetTop属性用于获取元素的顶边值,以及offsetWidth和offsetHeight获取元素的宽度和高度。

现在我们来使用定时器和offsetLeft来做一个物体的基础运动:

<html>
<head>
    <meta charset="utf-8"/>
    <title>无标题文档</title>
</head>
<body>
    <div id="div1"></div>
</body>
</html>
#div1 {
    width: 200px;
    height: 200px;
    background: red;
    position: absolute;
    left: 0;
    top: 50px;
}
setInterval(function () {
    var oDiv = document.getElementById('div1');

    oDiv.style.left = oDiv.offsetLeft + 10 + 'px';
}, 30);

计时器每运行一次,oDiv的left属性就会增加10,因此在计时器的作用下oDiv就运动了起来。效果如下:

【JavaScript从入门到精通】第十课  定时器的使用-02

现在,我们就可以着手开始制作我们的无缝滚动了。

首先,我们需要准备几张大小相同的图片,并用ul列表的形式放入html中。为了实现我们的滚动效果,我们将ul放在一个div,并将该div的position属性设置为relative,将ul的position属性设置为absolute,这样我们在制作运动效果时移动ul就可以了。

但我们思考一下,如果只是这么制作的话,仅仅只是实现了图片的移动,并没有做到无缝衔接,因此我们需要将布局进行修改:

【JavaScript从入门到精通】第十课  定时器的使用-02

如上图所示,实际上我们是将两份相同的图片组合拼接到了一起这样当图片移动,第一张图片在左侧消失时,又会在右侧出现。

这样离我们想实现的效果就很接近了。但试想一下,当两组图片全部滚动完毕后,依然没有后续内容出现,因此这里我们需要使用一个小小的障眼法:因为我们需要显示的图片只有四张,所以当第一组图片全部消失,第二组图片全部出现的时候(也就是滚动到一半的时候),其效果和页面刚刷新时是一致的,所以我们考虑当图片滚动到这个地方的时候,直接回到拉回到开头,这样就可以达到无缝滚动的效果了。 完整代码如下:

<html>
<head>
    <meta charset="utf-8"/>
    <title>无标题文档</title>
</head>
<body>
    <div id="div1">
        <ul>
            <li><img src="img2/1.jpg"/></li>
            <li><img src="img2/2.jpg"/></li>
            <li><img src="img2/3.jpg"/></li>
            <li><img src="img2/4.jpg"/></li>
        </ul>
    </div>
</body>
</html>
* {
    margin: 0;
    padding: 0;
}

#div1 {
    width: 712px;
    height: 108px;
    margin: 100px auto;
    position: relative;
    background: red;
    overflow: hidden;
}

#div1 ul {
    position: absolute;
    left: 0;
    top: 0;
}

#div1 ul li {
    float: left;
    width: 178px;
    height: 108px;
    list-style: none;
}
window.onload = function () {
    var oDiv = document.getElementById('div1');
    var oUl = oDiv.getElementsByTagName('ul')[0];
    var aLi = oUl.getElementsByTagName('li');

    oUl.innerHTML = oUl.innerHTML + oUl.innerHTML;
    oUl.style.width = aLi[0].offsetWidth * aLi.length + 'px';

    setInterval(function () {
        if (oUl.offsetLeft < -oUl.offsetWidth / 2) {
            oUl.style.left = '0';
        }
        oUl.style.left = oUl.offsetLeft - 2 + 'px';
    }, 30);
};

现在我们为它增加一个效果:不仅可以向左滚动,也可以向右滚动。需要修改的地方有两个:首先是每次定时器启动的时候将oUl的left值由-2变为+2,其次需要进行一个判断:当ul的left值已经>0的时候,同样将其拉回去。

<html>
<head>
    <meta charset="utf-8"/>
    <title>无标题文档</title>
</head>
<body>
<div id="div1">
    <ul>
        <li><img src="img2/1.jpg"/></li>
        <li><img src="img2/2.jpg"/></li>
        <li><img src="img2/3.jpg"/></li>
        <li><img src="img2/4.jpg"/></li>
    </ul>
</div>
</body>
</html>
* {
    margin: 0;
    padding: 0;
}

#div1 {
    width: 712px;
    height: 108px;
    margin: 100px auto;
    position: relative;
    background: red;
    overflow: hidden;
}

#div1 ul {
    position: absolute;
    left: 0;
    top: 0;
}

#div1 ul li {
    float: left;
    width: 178px;
    height: 108px;
    list-style: none;
}
window.onload = function () {
    var oDiv = document.getElementById('div1');
    var oUl = oDiv.getElementsByTagName('ul')[0];
    var aLi = oUl.getElementsByTagName('li');

    oUl.innerHTML = oUl.innerHTML + oUl.innerHTML;
    oUl.style.width = aLi[0].offsetWidth * aLi.length + 'px';

    setInterval(function () {
        if (oUl.offsetLeft < -oUl.offsetWidth / 2) {
            oUl.style.left = '0';
        }
        if (oUl.offsetLeft > 0) {
            oUl.style.left = -oUl.offsetWidth / 2 + 'px';
        }
        oUl.style.left = oUl.offsetLeft + 2 + 'px';
    }, 30);
};

 

效果如下:

【JavaScript从入门到精通】第十课  定时器的使用-02

接下来我们再给这个程序增加一个功能:鼠标移入时暂停,鼠标移出时停止。远离很简单,使用onmouseover事件和onmouseout事件与定时器的开启与停止搭配就可以了,不过这里为了让代码更加简洁,我们使用一个move函数取代之前写在定时器里的匿名函数。

window.onload=function ()
{
  var oDiv=document.getElementById('div1');
  var oUl=oDiv.getElementsByTagName('ul')[0];
  var aLi=oUl.getElementsByTagName('li');

  oUl.innerHTML=oUl.innerHTML+oUl.innerHTML;
  oUl.style.width=aLi[0].offsetWidth*aLi.length+'px';

  function move(){
    if(oUl.offsetLeft<-oUl.offsetWidth/2)
    {
      oUl.style.left='0';
    }
    if(oUl.offsetLeft>0)
    {
      oUl.style.left=-oUl.offsetWidth/2+'px';
    }
    oUl.style.left=oUl.offsetLeft+2+'px';
  }
  var timer=setInterval(move, 30);

  oDiv.onmouseover=function ()
  {
    clearInterval(timer);
  };

  oDiv.onmouseout=function ()
  {
    timer=setInterval(move, 30);
  };
};

最后,我们还想通过按钮来控制图片的运动方向。向左和向右运动的程序我们都已经写好,因此我们只需要将两端代码合并简化即可。我们用一个变量speed来代替之前的+2/-2,根据点击不同的按钮给speed赋不同值,这样不仅可以改变运动的方向,还可以改变运动的速度。

window.onload=function ()
{
  var oDiv=document.getElementById('div1');
  var oUl=oDiv.getElementsByTagName('ul')[0];
  var aLi=oUl.getElementsByTagName('li');

  var speed=-2;

  //oUl.innerHTML=oUl.innerHTML+oUl.innerHTML;
  oUl.innerHTML+=oUl.innerHTML;
  oUl.style.width=aLi[0].offsetWidth*aLi.length+'px';

  function move(){
    if(oUl.offsetLeft<-oUl.offsetWidth/2)
    {
      oUl.style.left='0';
    }
    if(oUl.offsetLeft>0)
    {
      oUl.style.left=-oUl.offsetWidth/2+'px';
    }
    oUl.style.left=oUl.offsetLeft+speed+'px';
  }
  var timer=setInterval(move, 30);

  oDiv.onmouseover=function ()
  {
    clearInterval(timer);
  };

  oDiv.onmouseout=function ()
  {
    timer=setInterval(move, 30);
  };

  document.getElementsByTagName('a')[0].onclick=function ()
  {
    speed=-2;
  };
  document.getElementsByTagName('a')[1].onclick=function ()
  {
    speed=2;
  };
};

如需转载,烦请注明出处:https://www.qdskill.com/javascript/506.html

发表评论

登录后才能评论