【原创】JavaScript无缝循环滚动效果(div非table版)-全程解析教程!(取代marquee,滚动效果详细讲解)
请只是想拷贝粘贴的人绕道,我想讲的是更详细的实现细节!!!
/******************* 对滚动一无所知的人看的 *******************/
预备
(js对象的几个的属性):
innerHTML:设置或获取位于对象起始和结束标签内的 HTML
(以下4个属性在api里可能查询不到)
scrollHeight: 获取对象的滚动高度。
scrollWidth:获取对象的滚动宽度
scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离
scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离
(注:网上有的教程用到了offsetTop等属性,其实可以不用的)
实现原理:通过计时器,不断设置滚动距离,实现滚动。为预防滚动到末尾,需要事先复制一个图集副本在到达末尾时起到继续滚动的“障眼法”。副本继续滚动到图集大小的距离时,我们会发现此时的情景和初始时的一模一样。所以在这个时机,偷偷把图集的距离打会到初始时的距离,再继续滚动。起来一个看起来像是无限在滚动的效果~
(css几个关键属性):
position:relative; //相对定位,根据外层标签的位置定位,设置后可以使用top,left等属性
overflow:hidden; //溢出隐藏,设置此属性前,需要先甚至对象的宽高,然后内容多的部分会隐藏不可见。
(html 滚动最好的基本结构):
<dl> <!--容器-->
<dt></dt> <!--图集或超链接文字-->
<dd></dd> <!--图集或超链接文字的副本-->
</dl>
(注:dl标签是一种自定义模块的,他可以嵌套dt模块内容,和dd模块备注。这种标签在div布局中常用)
/******************* 已经开始理解原理的人看的 *******************/
1.以前我学javascript的时候,提到这个js的无缝滚动,总有人告诉我,网上有很多实例可供直接套用。但是把这些事情留到做项目时解决,我才发现这是错误的,毕竟所有情况都未必和网上一样,网上有的总归是网上的,不是自己写的永远都不会理解,也无法根据实际情况做修改。本来这个东西就不难,禁不起研究,我的实现或许不是最好的,但是绝对是可以看懂的。
2.先评论下网上的滚动效果,实现细节暂且不提。table实现的直接无视!然后div实现的还有两种,其中一种是把<script></script>嵌在 body 最末尾,如果把这样的代码放在顶上(<table></table>后面),或者采用外链,是无法使用的。
如:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>嵌入在内容主体后的js</title>
</head>
<body>
<script type="text/javascript">实现代码</script>
</body>
</html>
不谈代码质量,先点评一点这样的做法:首先,他违背了web标准中,表现和显示分离的思想!其次,这样的代码可维护性低,复用性差。大家可以想想为什么他们要把滚动实现的代码嵌入到body末尾?而放在其他地方就不行?…… 起初可能有人会认为,是!DOCTYPE这句顶部申明犯罪了,其实并不是!而写这种代码的人,也主要是他没有完全读懂代码!
现在我们来分析代码!首先假设效果是图片向上滚动。这必须用 scrollTop 来不断获取和设置元素的滚动高度,至少这样才能“滚”起来,不然后面都没有戏!
那么大家应该都发现了,在一些情况下我们设置scrollTop,常常是没有反映的。如果我们尝试 alert(obj.scrollTop),系统也将自动无视掉。这种情况下,只有把js代码嵌入到body内容的末尾,才可以拿到和设置值。或者我们把代码块放到事件里,通过事件来触发,这样系统才鸟几声。这是为什么呢?
这是因为javascript在html元素被创建之前,就执行了代码。例如我们把js代码放在顶上,不用事件包裹,那么浏览器就会从整个html文档的申明开始,逐行往下执行。当它执行到 obj.scrollTop 这句的时候,因为我们获取的obj对象,在被创建之前读取了,所以系统会认为是错误,从而忽略。也就是说,此时我们写的 getElementById("")试图获取的对象,都还没有被创建好,所以所有的属性,更是不存在的!而当浏览器逐行继续往下执行时,所有的html元素才被逐一解析。故而,把js代码放在body内容的后面,才变成可行的。因为html对象被创建后之后,才逐行执行js代码,因此所有的对象和属性都可以拿到。
这种问题的完美结局办法:使用window的load事件!大家需要知道,window的load事件的执行时机是 当整个文档包括所有媒体对象,全部加载完毕后再执行。而这恰恰是我们需要的,当对象被创建之后再执行滚动效果,那么我们就可以成功获取对象,并且使用他的scrollTop属性实现滚动效果。(注:使用jQuery的朋友注意,jQuery的document.ready()事件执行时机是,文档加载之前执行)
以下是完整的竖向向上滚动效果:
html部分
<!-- 竖向滚动实例 -->
<dl id="dome">
<dt id="dome1">
<img src="images/7765.jpg" />
<img src="images/686786.jpg" />
<img src="images/mai.jpg" />
<img src="images/qingNiao.jpg" />
<img src="images/zhang.jpg" />
</dt>
<dd id="dome2"></dd>
</dl>
css部分
body{margin:0; padding:0;}
/************ 竖向滚动 ***********/
#dome{ position:relative; width:100px; height:300px;overflow:hidden; border:10px outset #CCC;}
#dome dl{margin:0; padding:0;}
#dome dd{margin:0; padding:0;}
#dome img{border:0; width:100px; height:100px;}
javascript部分
/**** window加载事件 ****/
window.onload = function(){
var dome = document.getElementById("dome");
var dome1 = document.getElementById("dome1");
var dome2 = document.getElementById("dome2");
dome2.innerHTML = dome1.innerHTML; //复制图集副本
/**** 滚动函数 ****/
function marquee(){
dome.scrollTop = (dome.scrollTop<=dome1.scrollHeight)?dome.scrollTop+1:1; //如果滚动距离小等于图集高度,那么当前距离加1,否则初始化距离为1
}
var marTime = window.setInterval(marquee,15); //循环调用
/**** 鼠标进入停止计时器和鼠标离开设置计时器 的事件 ****/
dome.onmouseover = function(){ window.clearInterval(marTime)}
dome.onmouseout = function(){ marTime = window.setInterval(marquee,15)}
}
就以上滚动,理解了之后还可以做各种各样的滚动效果。如果会遇到问题,大概也就是css设置的问题了。
/******************* 已经脱离复制代码来拼凑效果的人进阶的 *******************/
这里我提供一个全面的效果,包含:图片 上下左右滚动,文字上下左右滚动。我统一用一个函数,通过传参来实现。该函数会自动判断容器内容属于文字还是图片,然后调用默认的滚动效果。并且,所有的滚动效果都可以使用默认的,默认通常是最佳的视觉方向。
先附上html部分
<!-- 竖向滚动实例 -->
<dl id="dome">
<dt id="dome1">
<img src="images/7765.jpg" />
<img src="images/686786.jpg" />
<img src="images/mai.jpg" />
<img src="images/qingNiao.jpg" />
<img src="images/zhang.jpg" />
</dt>
<dd id="dome2"></dd>
</dl>
<!-- 横向滚动实例 -->
<!--<div id="dome">
<dl>
<dt id="dome1">
<img src="images/7765.jpg" />
<img src="images/686786.jpg" />
<img src="images/mai.jpg" />
<img src="images/qingNiao.jpg" />
<img src="images/zhang.jpg" />
</dt>
<dd id="dome2"></dd>
</dl>
</div>-->
<!-- 文字竖向滚动实例 -->
<!--<dl id="dome">
<dt id="dome1">
<a href="#">1.我是新闻列表项</a>
<a href="#">2.我是新闻列表项</a>
<a href="#">3.我是新闻列表项</a>
<a href="#">4.我是新闻列表项</a>
<a href="#">5.我是新闻列表项</a>
<a href="#">6.我是新闻列表项</a>
<a href="#">7.我是新闻列表项</a>
<a href="#">8.我是新闻列表项</a>
</dt>
<dd id="dome2"></dd>
</dl>-->
<!-- 文字横向滚动实例 -->
<!--<div id="dome">
<dl>
<dt id="dome1">
<a href="#">1.网站新创桑拿服务业务</a>
<a href="#">2.新人注册会员详细方法讲解请看这里</a>
<a href="#">3.《MySql入门很简单》清华大学出版社图书已经到库</a>
</dt>
<dd id="dome2"></dd>
</dl>
</div>-->
css部分
body{margin:0; padding:0;}
/************ 竖向滚动 ***********/
#dome{ position:relative; width:100px; height:300px;overflow:hidden; border:10px outset #CCC;}
#dome dl{margin:0; padding:0;}
#dome dd{margin:0; padding:0;}
#dome img{border:0; width:100px; height:100px;}
/************ 横向滚动 ***********/
/*#dome{ position:relative; width:425px; height:100px;overflow:hidden; border:10px outset #CCC;}
#dome dl{width:3000px; margin:0; padding:0; float:left;}
#dome dt{margin:0; padding:0; float:left;}
#dome dd{ margin:0; padding:0; float:left;}
#dome img{width:100px; height:100px; float:left;}*/
/************ 文字竖向滚动 ***********/
/*#dome{width:160px; height:170px; overflow:hidden; position:relative;margin:0;padding:0; line-height:25px; border:5px solid #930; font-size:14px;}
#dome dt{margin:0;padding:0;}
#dome dd{margin:0;padding:0;}
a{ text-decoration:none; color:#333; display:block; margin:0; padding:0; text-indent:1em; font-weight:600;}
a:hover{background:#333; color:#FFF; text-indent:2em; border:1px solid #CCC;}*/
/************ 文字横向滚动 ***********/
/*#dome{font-size:14px; width:500px; height:25px; border:5px solid #930; position:relative; overflow:hidden;}
#dome dl{width:1000%; margin:0; padding:0;}
#dome dt{margin:0; padding:0; float:left; line-height:25px;}
#dome dd{margin:0; padding:0; float:left; line-height:25px;}
#dome a{text-decoration:none; color:#C30; margin:0 12px; font-weight:600;}
#dome a:hover{text-decoration:underline; color:#F90;}*/
javascript部分
/***********************************
滚动效果函数:domeMarquee(domeID,dome1ID,dome2ID,domeTime,[domeScroll])
domeID //容器标签ID
dome1ID //图片集标签ID
dome2ID //图集副本标签ID
domeTime //滚动速度,值越小越快
domeScroll //滚动方向是可选参数,有默认值
************************************/
domeMarquee = function(domeID,dome1ID,dome2ID,domeTime){
if(arguments.length == 0){domeID = "dome";dome1ID = "dome1";dome2ID = "dome2";domeTime = 15}
var domeScroll = arguments[4]; //设置滚动方向的默认参数
var dome = document.getElementById(domeID); //获得容器对象
var dome1 = document.getElementById(dome1ID); //获得滚动内容对象
var dome2 = document.getElementById(dome2ID); //获得内容副本对象
var marqueeType = (dome.getElementsByTagName("img").length > 0)?"img":"text"; //返回容器中的滚动内容类型
dome2.innerHTML = dome1.innerHTML; //滚动内容复制一个副本
/* 向上滚动处理函数 */
function showTop(){
dome.scrollTop = (dome.scrollTop <= dome1.scrollHeight)?dome.scrollTop+1:1; //三元表达式控制滚动值
}
/* 向下滚动处理函数 */
function showBottom(){
dome.scrollTop = (dome.scrollTop <= 0)?dome1.scrollHeight:dome.scrollTop-1; //三元表达式控制滚动值
}
/* 向左滚动处理函数 */
function showLeft(){
dome.scrollLeft = (dome.scrollLeft <= dome1.scrollWidth)?dome.scrollLeft+1:1; //三元表达式控制滚动值
}
/* 向右滚动处理函数 */
function showRight(){
dome.scrollLeft = (dome.scrollLeft <= 0)?dome1.scrollWidth:dome.scrollLeft-1; //三元表达式控制滚动值
deBug(dome.scrollLeft,(dome.scrollLeft <= 0));
}
/* 动态选择调用的方法 */
switch(domeScroll){
case undefined: //滚动方向为默认值的情况
if(marqueeType == "img" && dome.scrollHeight < dome.scrollWidth)
domeScroll = showRight; //横向图集展示时的默认向右滚动
else if(marqueeType == "img" && dome.scrollWidth < dome.scrollHeight)
domeScroll = showBottom; //竖向图集展示时的默认向下滚动
else if(marqueeType == "text" && dome.scrollHeight < dome.scrollWidth)
domeScroll = showLeft; //横向文本展示时默认向左滚动
else if(marqueeType == "text" && dome.scrollWidth < dome.scrollHeight)
domeScroll = showTop; //竖向文本展示时默认向上滚动
else
alert("domeScroll默认属性错误");
break;
case "top":
domeScroll = showTop;
break;
case "bottom":
domeScroll = showBottom;
break;
case "left":
domeScroll = showLeft;
break;
case "right":
domeScroll = showRight;
break;
default:
alert("domeScroll输入参数非法");
}
/* 打开计时器 */
var scrollTime = window.setInterval(domeScroll,domeTime)
/* 鼠标进入容器体时,停止计时器(停止滚动动画) */
dome.onmouseover = function(){window.clearInterval(scrollTime)}
/* 鼠标离开容器体时,重开计时器(开始滚动动画) */
dome.onmouseout = function(){scrollTime = window.setInterval(domeScroll,domeTime)}
}
window.onload = function(){domeMarquee();};
如上javascript代码中,arguments是函数参数对象,该对象在函数创建是自动产生,是用户可以把传入的参数作为一个数组来访问。
/******************* 原创教程,转载请注明出处 *******************/

浙公网安备 33010602011771号