今天公司的首頁新增一個公告需求,類似於如下這段代碼的效果,做完以后仔細思考了一下其中的原理
在說原理之前建議先看看我上一篇 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>