图片上下左右的无缝滚动的实现

在网上浏览网页的时候,我们常常会看看无缝滚动的各种图片广告,但那是怎么实现的呢,今天我们就来说说如何实现图片的无缝滚动。

首先,我们来看看结构层,也就是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来实现

本文参考:

1、javascript无缝滚动

2、javascript无缝滚动2

posted @ 2016-04-29 16:33  huansky  阅读(1768)  评论(0编辑  收藏  举报