kxbdMarquee的基本使用(更改后的源码在文本末尾)
地址:https://github.com/erdouzhang/jquery.kxbdmarquee.js
- 使用方法及参数说明
* @DOM
* <div id="marquee">
* <ul>
* <li></li>
* <li></li>
* </ul>
* </div>
* @CSS
* #marquee {overflow:hidden;width:200px;height:50px;}
* @Usage
* $("#marquee").kxbdMarquee(options);
* @options
* isEqual:true, //所有滚动的元素长宽是否相等,true,false
* loop:0, //循环滚动次数,0时无限
* direction:"left", //滚动方向,"left","right","up","down"
* scrollAmount:1, //步长
* scrollDelay:20 //时长
*/
- html结构
<body>
<div id="marquee">
<ul>
<li>第一个li</li>
<li>第二个li</li>
<li>第三个li</li>
<li>第四个li</li>
<li>第五个li</li>
</ul>
</div>
</body>
- css
#marquee{
width: 200px;
height: 80px;
border: 1px solid #ccc;
overflow: hidden;
margin: 100px auto;
}
javaScript
$(function(){
$('#marquee').kxbdMarquee({ direction: "up",isEqual:false,scrollDelay: 100 });
})
实现效果
一, 结合tab栏切换时,定时器未被清空,导致滚动速度越来越快
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script src="./jquery-3.1.1.min.js"></script>
<script src="./jquery.kxbdMarquee.js"></script>
<script src="./demo.js"></script>
<body>
<div class="container">
<div class="top">
<button id="btnOne">tab一</button>
<button id="btnTwo">tab二</button>
</div>
<div id="marquee" class="scrollBox">
<ul>
<li>第一个li</li>
<li>第二个li</li>
<li>第三个li</li>
<li>第四个li</li>
<li>第五个li</li>
</ul>
</div>
</div>
</body>
<link rel="stylesheet" href="./demo.css">
</html>
css
#marquee{
width: 200px;
height: 80px;
border: 1px solid #ccc;
overflow: hidden;
}
.container{
width: 200px;
height: 120px;
margin: 100px auto;
}
.top{
margin-bottom: 15px;
}
.top button:hover{
cursor: pointer;
}
javaScript
$(function(){
$('#marquee').kxbdMarquee({ direction: "up",isEqual:false,scrollDelay: 100 });
let btns = ['btnOne','btnTwo']
let demoObj={
0:`<ul>
<li>第一个li</li>
<li>第二个li</li>
<li>第三个li</li>
<li>第四个li</li>
<li>第五个li</li>
</ul>`,
1:`<ul>
<li>第1个li</li>
<li>第2个li</li>
<li>第3个li</li>
<li>第4个li</li>
<li>第5个li</li>
</ul>`
}
$('.top button').on('click',function(e){
let htmlStr = demoObj[btns.indexOf(e.target.id)]
$('#marquee').empty()
$('#marquee').append(htmlStr)
$('#marquee').kxbdMarquee({ direction: "up",isEqual:false,scrollDelay: 100 });
})
})
原因:该插件滚动原理借助setInterval方法,切换tab栏时,会重复为元素添加setInterval事件,但插件内并无清空setInterval事件方法。
解决方案:将元素setInterval存储起来,在调用前判断是否已经绑定,若以绑定,则先清空,再重新绑定。
思路:
let scrolls = {'元素1':setInterval1,'元素2':setInterval2}
if(scrolls[元素1]){
clearInterval(scrolls[元素1]);
scrolls[元素1]=setInterval(xxxx);
}
二,当饰视口缩小时,滚动效果会莫名其妙的失效
原因:滚动基数为1px,网页缩小后导致滚动尺寸<1,因此失效,我个人解决方案是将基数修改为2。
三,当每行有两个li元素时,会出现空行的问题
原因: scrollSize此时为两个li元素的高度
解决方案:当滚动元素li元素为每行两个时,传入参数scrollHalf:true,并在kxbdMarquee内加个判断
调用
$('#marquee').kxbdMarquee({ direction: "up",isEqual:false,scrollDelay: 100,scrollHalf:true });
kxbdMarquee判断
if(opts.scrollHalf){ //此参数主要辨别li是否为每行2个(新增)
scrollSize = scrollSize/2
}
在此附上我修改后的kxbdMarquee源码
/**
* @classDescription 模拟Marquee,无间断滚动内容
* @author Lyc 修改
* @DOM
* <div id="marquee">
* <ul>
* <li></li>
* <li></li>
* </ul>
* </div>
* @CSS
* #marquee {overflow:hidden;width:200px;height:50px;}
* @Usage
* $("#marquee").kxbdMarquee(options);
* @options
* isEqual:true, //所有滚动的元素长宽是否相等,true,false
* loop:0, //循环滚动次数,0时无限
* direction:"left", //滚动方向,"left","right","up","down"
* scrollAmount:1, //步长
* scrollDelay:20 //时长
* scrollHalf:false //每行是否有两个li元素
*/
(function($){
var timeObj ={} //用对象来存储定时器: {className:对应的定时器} **元素务必拥有单独的class名
$.fn.kxbdMarquee=function(options){
var opts=$.extend({},$.fn.kxbdMarquee.defaults, options);
return this.each(function(){
var $marquee=$(this); //滚动元素容器
var _scrollObj=$marquee.get(0); //滚动元素容器DOM
var scrollW=$marquee.width(); //滚动元素容器的宽度
var scrollH=$marquee.height(); //滚动元素容器的高度
var $element=$marquee.children(); //滚动元素
var $kids=$element.children(); //滚动子元素
var scrollSize=0; //滚动元素尺寸
//滚动类型,1左右,0上下
var _type=(opts.direction=="left"||opts.direction=="right") ? 1:0;
//防止滚动子元素比滚动元素宽而取不到实际滚动子元素宽度
//$element.css(_type?"width":"height",10000);
// console.log('$element',$element,_type);
//获取滚动元素的尺寸
if(opts.isEqual){
scrollSize=Math.ceil($kids[_type?"outerWidth":"outerHeight"]()*$kids.length);
}else{
$kids.each(function(){
scrollSize+=Math.ceil($(this)[_type?"outerWidth":"outerHeight"]());
});
};
if(opts.scrollHalf){ //此参数主要辨别li是否为每行2个(新增)
scrollSize = scrollSize/2
}
//scrollSize = Math.floor(scrollSize)
// console.log('scrollSize',scrollSize,$kids.outerHeight());
//滚动元素总尺寸小于容器尺寸,不滚动
if(scrollSize<(_type?scrollW:scrollH)){return;};
//克隆滚动子元素将其插入到滚动元素后,并设定滚动元素宽度
$element.append($kids.clone()).css(_type?"width":"height",scrollSize*2);
var numMoved=0;
function scrollFunc(){
var _dir=(opts.direction=="left"||opts.direction=="right") ? "scrollLeft":"scrollTop";
//console.log('dir',_dir);
if (opts.loop>0) {
numMoved+=opts.scrollAmount;
if(numMoved>scrollSize*opts.loop){
_scrollObj[_dir]=0;
return clearInterval(timeObj[myName]);
};
};
if(opts.direction=="left"||opts.direction=="up"){
var newPos=_scrollObj[_dir]+2;
if(newPos>=scrollSize){
newPos-=scrollSize;
}
_scrollObj[_dir]=newPos;
}else{
var newPos=_scrollObj[_dir]-opts.scrollAmount;
if(newPos<=0){
newPos += scrollSize;
};
_scrollObj[_dir]=newPos;
};
};
let myName = $marquee.get(0).className
if(!timeObj[myName]){ //判断该dom对象是否已存在动画,若已存在,则先清除掉动画,再添加动画
timeObj[myName]=setInterval(scrollFunc, opts.scrollDelay);
}else if(timeObj[myName]){
clearInterval(timeObj[myName]);
//滚动开始
timeObj[myName]=setInterval(scrollFunc, opts.scrollDelay);
}
//鼠标划过停止滚动
$marquee.hover(function(){
clearInterval(timeObj[myName]);
},function(){
clearInterval(timeObj[myName]);
timeObj[myName]=setInterval(scrollFunc, opts.scrollDelay);
});
});
};
$.fn.kxbdMarquee.defaults={
isEqual:true, //所有滚动的元素长宽是否相等,true,false
loop: 0, //循环滚动次数,0时无限
direction: "left", //滚动方向,"left","right","up","down"
scrollAmount:1, //步长
scrollDelay:20 //时长
};
$.fn.kxbdMarquee.setDefaults=function(settings) {
$.extend( $.fn.kxbdMarquee.defaults, settings );
};
})(jQuery);