[原创]Javascript实现marquee无间隙/有间隙滚动
<marquee> 标签不属于W3C标准,在XHTML1.0后被废弃,仅IE5/IE6支持,FF和IE7已完全弃用。但滚动效果仍是网页常用需求,Flash通用性差,常规JS方案存在兼容性差、无法无缝滚动、内容不足时静止等问题。
为此开发了一款JS类 JsMarquee,可完全替代<marquee>,支持无缝/有间隙二维滚动,兼容主流浏览器,已在多个项目中验证可用。
资源下载与演示
核心JS代码
1. 主类定义(Marquee)
/*JS Marquee Version 1.2(Javascript实现Marquee的效果,实现无缝/有间隙的二维滚动效果)*/
/*Author : ChenReal
Email : chenreal@21cn.com
Date : 2007-10-22*/
function Marquee(MarName)
{
this.ID = document.getElementById(MarName);
this.Speed = 30; //数字越大速度越慢
this.Direction = 0;//滚动方向:0代表左;1代表右;2代表上;3代表下
this.Width = 0;//宽度
this.Height = 0;//高度
this.Space = 0;//是否有间隙:0代表否;1代表是
this.Tag = "p";//滚动内容的标签,默认是<p>,也可以是<ul>,实践证明:<p>与<ul>不能嵌套使用。其他标签暂时不推荐。
//开始滚动
this.Start = function(){
MarqueeStart(this,this.Direction,this.Width,this.Height,this.Speed,this.Space,this.Tag);
}
//停止滚动并释放对象
this.End = function(){
MarqueeEnd(this);
}
}
2. 滚动初始化(MarqueeStart)
function MarqueeStart(Mar,Direction,Width,Height,Speed,Space,Tag){
var msobj;
if(typeof(Mar) == "string"){
msobj = new Marquee(Mar);
}
if(typeof(Mar) == "object"){
msobj = Mar;
}
if(!msobj.ID) return;
msobj.ID.style.width = Width + "px";
msobj.ID.style.height = Height + "px";
msobj.ID.style.overflow = msobj.ID.style.overflowX = msobj.ID.style.overflowY = "hidden";
msobj.Direction = Direction;
msobj.Width = Width;
msobj.Height = Height;
msobj.Speed = Speed;
msobj.Space = Space;
msobj.Tag = Tag;
msobj.InnerDiv = msobj.ID.getElementsByTagName("div")[0];
if(!msobj.InnerDiv) return;
msobj.InnerDiv.innerHTML += msobj.InnerDiv.innerHTML;
msobj.Inner = msobj.ID.getElementsByTagName(Tag);
if(!msobj.Inner) return;
switch(Direction)
{
case 2:
msobj.InnerDiv.style.width = Width + "px";
msobj.Inner[0].style.width =Width + "px";
msobj.Inner[1].style.width =Width + "px";
if(Height>=msobj.Inner[1].offsetHeight || msobj.Space ==1){
msobj.Inner[0].style.paddingTop = Height + "px";
msobj.Inner[1].style.paddingTop = Height + "px";;
}
break;
case 3:
msobj.InnerDiv.style.width = Width + "px";
msobj.Inner[0].style.width =Width + "px";
msobj.Inner[1].style.width =Width + "px";
if(Height>=msobj.Inner[1].offsetHeight || msobj.Space ==1){
msobj.Inner[0].style.paddingBottom = Height + "px";
msobj.Inner[1].style.paddingBottom = Height + "px";
}
break;
default:
msobj.InnerDiv.noWrap = true;
if(Width >= msobj.Inner[1].offsetWidth || msobj.Space ==1){
msobj.Inner[0].style.paddingLeft = Width + "px";
msobj.Inner[1].style.paddingLeft = Width + "px";
}
break;
}
msobj.ID.onmouseover = function(){
clearInterval(msobj.TimerID);
}
msobj.ID.onmouseout = function(){
clearInterval(msobj.TimerID);
msobj.TimerID = funcInterval(MarqueeScroll,msobj.Speed,msobj);
}
msobj.TimerID = funcInterval(MarqueeScroll,msobj.Speed,msobj);
}
3. 滚动核心逻辑(MarqueeScroll)
function MarqueeScroll(Mar){
switch(Mar.Direction)
{
case 0:
if(Mar.Inner[1].offsetWidth-Mar.ID.scrollLeft<=0)
Mar.ID.scrollLeft-=Mar.Inner[0].offsetWidth;
else{
Mar.ID.scrollLeft++;
}
break;
case 1:
if(Mar.ID.scrollLeft==0)
Mar.ID.scrollLeft=Mar.Inner[1].offsetWidth;
else{
Mar.ID.scrollLeft--;
}
break;
case 2:
if(Mar.Inner[1].offsetHeight-Mar.ID.scrollTop<=0)
Mar.ID.scrollTop-=Mar.Inner[0].offsetHeight;
else{
Mar.ID.scrollTop++;
}
break;
case 3:
if(Mar.ID.scrollTop<=0)
Mar.ID.scrollTop = Mar.Inner[1].offsetHeight;
else{
Mar.ID.scrollTop--;
}
break;
}
}
4. 停止滚动(MarqueeEnd)
function MarqueeEnd(Mar){
if(!Mar)return;
if(typeof(Mar.TimerID) == "number") {
clearInterval(Mar.TimerID);
Mar = null;
}
}
5. 定时器封装(funcInterval)
function funcInterval(funcName,time){
var args=[];
for(var i=2;i<arguments.length;i++){
args.push(arguments[i]);
}
return window.setInterval(function(){
funcName.apply(this,args);
},time);
}
HTML使用示例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<script src="js/marquee.js" language="javascript" type="text/javascript"></script>
<script language="javascript">
window.onload = function(){
var mar = new Marquee("marquee");
mar.Direction = 0;
mar.Width = 270;
mar.Height = 16;
mar.Speed = 20;
mar.Space = 0;
mar.Start();
MarqueeStart("marquee1",1,70,16,30,0,"p");
MarqueeStart("marquee2",2,150,100,30,1,"p");
MarqueeStart("marquee3",3,20,62,30,0,"p");
MarqueeStart("marquee4",0,70,50,30,0,"ul");
}
</script>
<style>
.marquee {border:1px solid #999999;}
.marquee div{width:1000%;}
.marquee div p{display:block; float:left; margin:0px;}
.marquee div ul{display:block; float:left; margin:0px;padding:0px;}
.marquee div ul li{float:left; display:block; border:solid 1px #666666; padding:14px 21px 14px 21px; margin:1px 10px 1px 10px; list-style:none;}
</style>
<title>Marquee Test</title>
</head>
<body>
<div id="marquee" class="marquee">
<div>
<p>横向有间隙从左到右滚动</p>
</div>
</div>
<div id="marquee1" class="marquee">
<div>
<p>间无向横 ~~~~~动滚左到右从隙</p>
</div>
</div>
<div id="marquee2" class="marquee">
<div>
<p>从上到下<br>有间隙滚动</p>
</div>
</div>
<div id="marquee3" class="marquee">
<div>
<p>从<br>下<br>到<br>上<br>有<br>间<br>隙<br>滚<br>动</p>
</div>
</div>
<div id="marquee4" class="marquee">
<div>
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
</div>
</div>
</body>
</html>
核心参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
Direction | 数字 | 滚动方向:0=左、1=右、2=上、3=下 |
Speed | 数字 | 滚动速度,数值越大速度越慢(默认30) |
Width/Height | 数字 | 滚动容器的宽/高(单位:px) |
Space | 数字 | 是否有间隙:0=无缝滚动、1=有间隙滚动 |
Tag | 字符串 | 滚动内容的标签,仅支持p/ul(不可嵌套使用) |
核心方法
| 方法 | 说明 |
|---|---|
Start() | 启动滚动 |
End() | 停止滚动并释放对象 |
特性
- 兼容主流浏览器(替代废弃的
<marquee>); - 支持横向/纵向滚动,无缝/有间隙模式自由切换;
- 内容长度不足时仍可正常滚动,无静止问题;
- 鼠标悬停时停止滚动,离开后恢复;
- 支持
p/ul标签承载滚动内容,适配不同布局场景。