以更少的代碼實現相同的效果應該是我們寫程式的究極目標,當然可讀性不能丟。在第一部分最後一個運行框,我已經做了這樣的探索。不過換湯不換藥,還是來來回回在scrollTop/scrollLeft與offsetTop/offsetLeft上做文章。總的思路基本是這樣,讓某個元素整體向某個方向移動,這樣它裡面的內容(圖片或文字)就跟著移動,當元素移動到某一個距離後就回到原點。為了防止內容移著移著就沒有了,我們需要兩套相同的內容。在第一部分,第二套內容是動態產生的,並複製到另一個兄弟元素中,這在水平滾動時,我們需要花一些周折來讓所有內容水平排列在一起。我就想,如果把第二套內容直接加在相同的元素是否效果會更好呢?起碼CSS也少寫一點。用scrollTop/scrollLeft實現滾動,還有一個缺點,它對父容器的寬度與高度有嚴格的規定的。比如我們想上下滾動圖片,ul作為容器,li的圖片為滾動內容,那麼ul的高至少為圖片的高的兩倍(我們假設每張圖片的尺寸都是相等的),否則就動不了。鑒此,我開發了新一代的無縫滾動函數。
<ul id="marquee"> <li> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s017.jpg" alt="無縫滾動"/></a> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s018.jpg" alt="無縫滾動"/></a> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s019.jpg" alt="無縫滾動"/></a> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s020.jpg" alt="無縫滾動"/></a> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s021.jpg" alt="無縫滾動"/></a> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s022.jpg" alt="無縫滾動"/></a> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s023.jpg" alt="無縫滾動"/></a> </li></ul>
#marquee ,#marquee li { padding:0; margin:0; } #marquee { position:relative; list-style:none; height:150px; width:200px; overflow:hidden; border:10px solid #369; } #marquee li { position:absolute; } #marquee img { display:block; border:0; }
var Marquee = function(id){ try{document.execCommand("BackgroundImageCache", false, true);}catch(e){}; var container = document.getElementById(id), slide = container.getElementsByTagName("li")[0], speed = arguments[1] || 10, delta = 0,//當前滾動的位置 critical = slide.offsetHeight;//臨界值 slide.innerHTML += slide.innerHTML; var rolling = function(){ delta == -critical ? delta = 0 : delta--; slide.style.top = delta + "px"; } var timer = setInterval(rolling,speed)//設定定時器 container.onmouseover=function() {clearInterval(timer)}//滑鼠移到marquee上時,清除定時器,停止滾動 container.onmouseout=function() {timer=setInterval(rolling,speed)}//滑鼠移開時重設定時器 } window.onload = function(){ Marquee("marquee"); }
<br /><!doctype html><br /><title>javascript無縫滾動 by 司徒正美</title><br /><meta charset="utf-8"/><br /><meta name="keywords" content="javascript無縫滾動 by 司徒正美" /><br /><meta name="description" content="javascript無縫滾動 by 司徒正美" /><br /><base href="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/"><br /><style type="text/css"><br /> h1 {<br /> font:400 16px/1 "Microsoft YaHei",KaiTi_GB2312,SimSun<br /> }<br /> #marquee ,#marquee li {<br /> padding:0;<br /> margin:0;<br /> }<br /> #marquee {<br /> position:relative;<br /> list-style:none;<br /> height:150px;<br /> width:200px;<br /> overflow:hidden;<br /> border:10px solid #369;<br /> }<br /> #marquee li {<br /> position:absolute;<br /> }<br /> #marquee img {<br /> display:block;<br /> border:0;<br /> }<br /></style><br /><script type="text/javascript"><br /> var Marquee = function(id){<br /> try{document.execCommand("BackgroundImageCache", false, true);}catch(e){};<br /> var container = document.getElementById(id),<br /> slide = container.getElementsByTagName("li")[0],<br /> speed = arguments[1] || 10,<br /> delta = 0,//當前滾動的位置<br /> critical = slide.offsetHeight;//臨界點<br /> slide.innerHTML += slide.innerHTML;<br /> var rolling = function(){<br /> delta == -critical ? delta = 0 : delta--;<br /> slide.style.top = delta + "px";<br /> }<br /> var timer = setInterval(rolling,speed)//設定定時器<br /> container.onmouseover=function() {clearInterval(timer)}//滑鼠移到marquee上時,清除定時器,停止滾動<br /> container.onmouseout=function() {timer=setInterval(rolling,speed)}//滑鼠移開時重設定時器<br /> }<br /> window.onload = function(){<br /> Marquee("marquee");<br /> }<br /></script><br /><h1>javascript無縫滾動(向上滾動) by 司徒正美</h1><br /><base href="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/"><br /><ul id="marquee"><br /> <li><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s017.jpg" alt="無縫滾動 by 司徒正美"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s018.jpg" alt="無縫滾動 by 司徒正美"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s019.jpg" alt="無縫滾動 by 司徒正美"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s020.jpg" alt="無縫滾動 by 司徒正美"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s021.jpg" alt="無縫滾動 by 司徒正美"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s022.jpg" alt="無縫滾動 by 司徒正美"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s023.jpg" alt="無縫滾動 by 司徒正美"/></a><br /> </li><br /></ul><br />
運行代碼
向下滾動也很容易,只不過一開始把它定位到第一套內容與第二套內容之間,也就是slide.offsetHeight,不過我們需要把它改成負數讓向整體向下移動,然後再慢慢向上移動。
<br /><!doctype html><br /><title>javascript無縫滾動 by 司徒正美</title><br /><meta charset="utf-8"/><br /><meta name="keywords" content="javascript無縫滾動 by 司徒正美" /><br /><meta name="description" content="javascript無縫滾動 by 司徒正美" /><br /><base href="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/"><br /><style type="text/css"><br /> h1 {<br /> font:400 16px/1 "Microsoft YaHei",KaiTi_GB2312,SimSun<br /> }<br /> #marquee ,#marquee li {<br /> padding:0;<br /> margin:0;<br /> }<br /> #marquee {<br /> position:relative;<br /> list-style:none;<br /> height:150px;<br /> width:200px;<br /> overflow:hidden;<br /> border:10px solid #B45B3E;<br /> }<br /> #marquee li {<br /> position:absolute;<br /> }<br /> #marquee img {<br /> display:block;<br /> border:0;<br /> }<br /></style><br /><script type="text/javascript"><br /> var Marquee = function(id){<br /> try{document.execCommand("BackgroundImageCache", false, true);}catch(e){};<br /> var container = document.getElementById(id),<br /> slide = container.getElementsByTagName("li")[0],<br /> speed = arguments[1] || 10,<br /> critical = slide.offsetHeight,//臨界值<br /> delta = -critical;<br /> slide.innerHTML += slide.innerHTML;<br /> var rolling = function(){<br /> delta == 0 ? delta = -critical : delta++;<br /> slide.style.top = delta + "px";<br /> }<br /> var timer = setInterval(rolling,speed)//設定定時器<br /> container.onmouseover=function() {clearInterval(timer)}//滑鼠移到marquee上時,清除定時器,停止滾動<br /> container.onmouseout=function() {timer=setInterval(rolling,speed)}//滑鼠移開時重設定時器<br /> }<br /> window.onload = function(){<br /> Marquee("marquee");<br /> }<br /></script><br /><h1>javascript無縫滾動(向下滾動) by 司徒正美</h1><br /><base href="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/"><br /><ul id="marquee"><br /> <li><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s017.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s018.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s019.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s020.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s021.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s022.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s023.jpg" alt="無縫滾動"/></a><br /> </li><br /></ul><br />
運行代碼
實現水平移動也比第一部分容易,結構層完全不用改動,表現層也改動很少。
#marquee ,#marquee li { padding:0; margin:0; } #marquee { position:relative; list-style:none; height:150px; width:200px; overflow:hidden; border:10px solid #B45B3E; } #marquee li { position:absolute; width:1000%;/*★★新增加★★*/ } #marquee a { float:left;/*★★新增加★★*/ } #marquee img { display:block; border:0; }
痛點是如何擷取那個臨界值,也就是夾在第一套內容與第二個套內容之間的那個位置。由於第二套內容我們並沒有外套一個元素,因此我們需要從滾動對象下手。滾動對象都是a元素,我們需要計算出第二套內容的第一個a元素到達父元素左邊的距離。這個值就是我們要求的臨界值。明白這點,就輕鬆了。
//*************略********* slide.innerHTML += slide.innerHTML; var item = slide.getElementsByTagName("a"), critical = item[item.length/2].offsetLeft,//臨界值//*************略*********
<br /><!doctype html><br /><title>javascript無縫滾動 by 司徒正美</title><br /><meta charset="utf-8"/><br /><meta name="keywords" content="javascript無縫滾動 by 司徒正美" /><br /><meta name="description" content="javascript無縫滾動 by 司徒正美" /><br /><base href="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/"><br /><style type="text/css"><br /> h1 {<br /> font:400 16px/1 "Microsoft YaHei",KaiTi_GB2312,SimSun<br /> }<br /> #marquee ,#marquee li {<br /> padding:0;<br /> margin:0;<br /> }<br /> #marquee {<br /> position:relative;<br /> list-style:none;<br /> height:150px;<br /> width:200px;<br /> overflow:hidden;<br /> border:10px solid #8080C0;<br /> }<br /> #marquee li {<br /> position:absolute;<br /> width:1000%;/*新增加*/<br /> }<br /> #marquee a {<br /> float:left;/*新增加*/<br /> }<br /> #marquee img {<br /> display:block;<br /> border:0;<br /> }<br /></style><br /><script type="text/javascript"><br /> var Marquee = function(id){<br /> try{document.execCommand("BackgroundImageCache", false, true);}catch(e){};<br /> var container = document.getElementById(id),<br /> slide = container.getElementsByTagName("li")[0],<br /> speed = arguments[1] || 10;<br /> slide.innerHTML += slide.innerHTML;<br /> var item = slide.getElementsByTagName("a"),<br /> critical = item[item.length/2].offsetLeft,//臨界值<br /> delta = 0;<br /> var rolling = function(){<br /> delta == -critical ? delta = 0 : delta--;<br /> slide.style.left = delta + "px";<br /> }<br /> var timer = setInterval(rolling,speed)//設定定時器<br /> container.onmouseover=function() {clearInterval(timer)}//滑鼠移到marquee上時,清除定時器,停止滾動<br /> container.onmouseout=function() {timer=setInterval(rolling,speed)}//滑鼠移開時重設定時器<br /> }<br /> window.onload = function(){<br /> Marquee("marquee");<br /> }<br /></script><br /><h1>javascript無縫滾動(向左滾動) by 司徒正美</h1><br /><base href="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/"><br /><ul id="marquee"><br /> <li><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s017.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s018.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s019.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s020.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s021.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s022.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s023.jpg" alt="無縫滾動"/></a><br /> </li><br /></ul><br />
運行代碼
下面是向右滾動,由雩都是不足20行的指令碼,應該一看源碼就明白,不詳述了。
<br /><!doctype html><br /><title>javascript無縫滾動 by 司徒正美</title><br /><meta charset="utf-8"/><br /><meta name="keywords" content="javascript無縫滾動 by 司徒正美" /><br /><meta name="description" content="javascript無縫滾動 by 司徒正美" /><br /><base href="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/"><br /><style type="text/css"><br /> h1 {<br /> font:400 16px/1 "Microsoft YaHei",KaiTi_GB2312,SimSun<br /> }<br /> #marquee ,#marquee li {<br /> padding:0;<br /> margin:0;<br /> }<br /> #marquee {<br /> position:relative;<br /> list-style:none;<br /> height:150px;<br /> width:200px;<br /> overflow:hidden;<br /> border:10px solid #6cc;<br /> }<br /> #marquee li {<br /> position:absolute;<br /> width:1000%;<br /> }<br /> #marquee a {<br /> float:left;<br /> }<br /> #marquee img {<br /> display:block;<br /> border:0;<br /> }<br /></style><br /><script type="text/javascript"><br /> var Marquee = function(id){<br /> try{document.execCommand("BackgroundImageCache", false, true);}catch(e){};<br /> var container = document.getElementById(id),<br /> slide = container.getElementsByTagName("li")[0],<br /> speed = arguments[1] || 10;<br /> slide.innerHTML += slide.innerHTML;<br /> var item = slide.getElementsByTagName("a"),//臨界點<br /> critical = item[item.length/2].offsetLeft,<br /> delta = -critical;<br /> var rolling = function(){<br /> delta == 0 ? delta = -critical : delta++;<br /> slide.style.left = delta + "px";<br /> }<br /> var timer = setInterval(rolling,speed)//設定定時器<br /> container.onmouseover=function() {clearInterval(timer)}//滑鼠移到marquee上時,清除定時器,停止滾動<br /> container.onmouseout=function() {timer=setInterval(rolling,speed)}//滑鼠移開時重設定時器<br /> }<br /> window.onload = function(){<br /> Marquee("marquee");<br /> }<br /></script><br /><h1>javascript無縫滾動(向右滾動) by 司徒正美</h1><br /><base href="http://images.cnblogs.com/cnblogs_com/rubylouvre/199042/"><br /><ul id="marquee"><br /> <li><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s017.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s018.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s019.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s020.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s021.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s022.jpg" alt="無縫滾動"/></a><br /> <a href="http://www.cnblogs.com/rubylouvre/"><img src="o_s023.jpg" alt="無縫滾動"/></a><br /> </li><br /></ul><br />
運行代碼
我們可以把上面四個函數合并成一個函數,結構層與表現層參照向上滾動。
var Marquee = function(id){ try{document.execCommand("BackgroundImageCache", false, true);}catch(e){}; var container = document.getElementById(id), slide = container.getElementsByTagName("li")[0], options = arguments[1] || {}, speed = options.speed || 10, direction = options.direction || "left"; slide.innerHTML += slide.innerHTML; var item = slide.getElementsByTagName("a"), critical,delta,rolling,field; if(direction == "left" || direction == "right"){ slide.style.cssText = "width:1000%"; for(var i=0 ,l=item.length; i<l;i++){ item[i].style.cssText = "float:left"; } field = "left"; critical = item[item.length/2].offsetLeft; }else if(direction == "up" || direction == "down"){ field = "top"; critical = item[item.length/2].offsetTop; } if(direction == "up" || direction == "left"){ delta = 0; rolling = function(){ delta == -critical ? delta = 0 : delta--; slide.style[field] = delta + "px"; } }else if(direction == "down" || direction == "right"){ delta = -critical; rolling = function(){ delta == 0 ? delta = -critical : delta++; slide.style[field] = delta + "px"; } } var timer = setInterval(rolling,speed)//設定定時器 container.onmouseover=function() {clearInterval(timer)}//滑鼠移到marquee上時,清除定時器,停止滾動 container.onmouseout=function() {timer=setInterval(rolling,speed)}//滑鼠移開時重設定時器 }
使用:
Marquee("marquee",{speed:35,direction:"up"});
有了這個我們實現另一種圖片輪換就容易了,這裡先做個預告吧。本文到此為止。