js从右向左无缝滚动原理

今天公司的首页新增一个公告需求,类似于如下这段代码的效果,做完以后仔细思考了一下其中的原理

在说原理之前建议先看看我上一篇 HTML精确定位:scrollLeft,scrollWidth,clientWidth,offsetWidth之完全详解 这篇文章,里面例图即视化的解释了各种定位的不同,以及在各浏览器下不同的解析结果。

不敲太多的文字,直接上代码,干货都在注释里

<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>js文字向左无缝滚动</title>
</head>
<body>
<style type="text/css"> .qimo8{ overflow:hidden; width:815px;}/*外层div,设置公告可见范围*/ .qimo8 .qimo {/*width:9999999999px;*/width:8000%; height:30px;}/*公告内容,给内容预留足够的空间宽度*/
.qimo8 .qimo div
{ float:left;}/*包括demo1和demo2 让两个层合并为一排,也是无缝对接的关键*/
.qimo8 .qimo ul{float:left; height:30px; overflow:hidden; zoom:}
.qimo8 .qimo ul li{float:left; line-height:30px; list-style:none;}
.qimo8 li a
{margin-right:10px;color:#444;}
</style>

<div id="demo" class="qimo8">
  <div class="qimo">
    <div id="demo1">
      <ul>
        <li><a href='#' >11111111111111111</a></li>
        <li><a href='#' >22222222222222222</a></li>
        <li><a href='#' >11111111111111111</a></li>
        <li><a href='#' >22222222222222222</a></li>
        <li><a href='#' >11111111111111111</a></li>
        <li><a href='#' >22222222222222222</a></li>
      </ul>
    </div>
    <div id="demo2"></div>
  </div>
</div>

<script type="text/javascript">
var demo = document.getElementById("demo");//外层可视模块
var demo1 = document.getElementById("demo1"); //内层滚动内容模块1
var demo2 = document.getElementById("demo2");//
内层滚动内容模块2 无缝对接到1后面的内容
demo2.innerHTML=document.getElementById("demo1").innerHTML; //把demo1的内容复制一份到demo2中
//关键人物上场
function Marquee(){ 
  /*创建一个滚动函数
1)demo.scrollLeft 是获取可视区 demo 位于对象左边这界和窗口中目前可见内容的最左端之间的距离,一般从0开始
   2)demo2.offsetWidth 是获取 demo2 相对于版面或由父坐标 offsetParent 属性指定的父坐标的宽度,一般是固定的,就是当前滚动内容的总宽度;
   3)demo.scrollLeft和demo2.offsetWidth相减后值是等于0或不小于0时说明 demo1的内容已经完全滚动到可视范围之外;
那么,就让
demo.scrollLeft 的值重新等于0,(这里用的是demo.scrollLeft减于demo2.offsetWidth的结果,不出问题都应该是0),
    视觉上相当于demo1替换了当前demo2相同位置,其实两个模块并没有替换,只是重复了初始化时的状态,重新开始从demo1开始
4)
demo.scrollLeft和demo2.offsetWidth相减后值小于0 就让 demo.scrollLeft 的数值一直增加,向左移动
   */
  if(demo.scrollLeft-demo2.offsetWidth>=0){ 
    demo.scrollLeft
-=demo1.offsetWidth;
//在这里把值打印出来
console.log(
"demo的scrollLeft值减去: "+
demo.scrollLeft+"-demo1的offsetWidth值 : "+demo1.offsetWidth+"等于"+(demo.scrollLeft-=demo1.offsetWidth));
  }else{ 
    console.log(
"demo的scrollLeft值为: "+demo.scrollLeft+"减去demo2.offsetWidth :"+demo2.offsetWidth+"等于==="+ (demo.scrollLeft-demo2.offsetWidth));
    demo.scrollLeft
++;
  }
}

//下面这段 就要讲到js的异步周期函数了,不知道我这样称呼它算不算准确,
setInterval 也可以写成 window.setInterval
/*
特别说明:凡是属于window对象的方法都可以直接使用,无需使用window对象调用。
如果不关闭游览器或者调用 clearInterval()将会永远的执行下去。
返回值是当前定时器的唯一ID标识。
有疑问的推荐看下面两篇文章,里面讲解的非常全面仔细
http://www.softwhy.com/forum.php?mod=viewthread&tid=3972
http://www.softwhy.com/forum.php?mod=viewthread&tid=6940
*/

//先把函数保存在一个变量中,
var myvar=setInterval(Marquee,20);

//下面是
onmouseout 和 onmouseover的常规用法了,鼠标移开开始滚动,鼠标移上clearInterval暂停
demo.onmouseout=function (){myvar=setInterval(Marquee,20);} 
demo.onmouseover=function(){clearInterval(myvar);}

</script>
</body>
</html>  

 

posted @ 2017-04-24 20:39  资深好孩子  阅读(3820)  评论(0编辑  收藏  举报