Marquee.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /**
  2. * @classDescription 超级Marquee,可做图片导航,图片轮换
  3. * @author Aken Li(www.kxbd.com)
  4. * @date 2009-07-27
  5. * @dependence jQuery 1.3.2
  6. * @DOM
  7. * <div id="marquee">
  8. * <ul>
  9. * <li></li>
  10. * <li></li>
  11. * </ul>
  12. * </div>
  13. * @CSS
  14. * #marquee {width:200px;height:50px;overflow:hidden;}
  15. * @Usage
  16. * $('#marquee').kxbdSuperMarquee(options);
  17. * @options
  18. * distance:200,//一次滚动的距离
  19. * duration:20,//缓动效果,单次移动时间,越小速度越快,为0时无缓动效果
  20. * time:5,//停顿时间,单位为秒
  21. * direction: 'left',//滚动方向,'left','right','up','down'
  22. * scrollAmount:1,//步长
  23. * scrollDelay:20//时长,单位为毫秒
  24. * isEqual:true,//所有滚动的元素长宽是否相等,true,false
  25. * loop: 0,//循环滚动次数,0时无限
  26. * btnGo:{left:'#goL',right:'#goR'},//控制方向的按钮ID,有四个属性left,right,up,down分别对应四个方向
  27. * eventGo:'click',//鼠标事件
  28. * controlBtn:{left:'#goL',right:'#goR'},//控制加速滚动的按钮ID,有四个属性left,right,up,down分别对应四个方向
  29. * newAmount:4,//加速滚动的步长
  30. * eventA:'mouseenter',//鼠标事件,加速
  31. * eventB:'mouseleave',//鼠标事件,原速
  32. * navId:'#marqueeNav', //导航容器ID,导航DOM:<ul><li>1</li><li>2</li><ul>,导航CSS:.navOn
  33. * eventNav:'click' //导航事件
  34. */
  35. (function($){
  36. $.fn.kxbdSuperMarquee = function(options){
  37. var opts = $.extend({},$.fn.kxbdSuperMarquee.defaults, options);
  38. return this.each(function(){
  39. var $marquee = $(this);//滚动元素容器
  40. var _scrollObj = $marquee.get(0);//滚动元素容器DOM
  41. var scrollW = $marquee.width();//滚动元素容器的宽度
  42. var scrollH = $marquee.height();//滚动元素容器的高度
  43. var $element = $marquee.children(); //滚动元素
  44. var $kids = $element.children();//滚动子元素
  45. var scrollSize=0;//滚动元素尺寸
  46. var _type = (opts.direction == 'left' || opts.direction == 'right') ? 1:0;//滚动类型,1左右,0上下
  47. var scrollId, rollId, isMove, marqueeId;
  48. var t,b,c,d,e; //滚动动画的参数,t:当前时间,b:开始的位置,c:改变的位置,d:持续的时间,e:结束的位置
  49. var _size, _len; //子元素的尺寸与个数
  50. var $nav,$navBtns;
  51. var arrPos = [];
  52. var numView = 0; //当前所看子元素
  53. var numRoll=0; //轮换的次数
  54. var numMoved = 0;//已经移动的距离
  55. //防止滚动子元素比滚动元素宽而取不到实际滚动子元素宽度
  56. $element.css(_type?'width':'height',10000);
  57. //获取滚动元素的尺寸
  58. var navHtml = '<ul>';
  59. if (opts.isEqual) {
  60. _size = $kids[_type?'outerWidth':'outerHeight']();
  61. _len = $kids.length;
  62. scrollSize = _size * _len;
  63. for(var i=0;i<_len;i++){
  64. arrPos.push(i*_size);
  65. navHtml += '<li>'+ (i+1) +'</li>';
  66. }
  67. }else{
  68. $kids.each(function(i){
  69. arrPos.push(scrollSize);
  70. scrollSize += $(this)[_type?'outerWidth':'outerHeight']();
  71. navHtml += '<li>'+ (i+1) +'</li>';
  72. });
  73. }
  74. navHtml += '</ul>';
  75. //滚动元素总尺寸小于容器尺寸,不滚动
  76. if (scrollSize<(_type?scrollW:scrollH)) return;
  77. //克隆滚动子元素将其插入到滚动元素后,并设定滚动元素宽度
  78. $element.append($kids.clone()).css(_type?'width':'height',scrollSize*2);
  79. //轮换导航
  80. if (opts.navId) {
  81. $nav = $(opts.navId).append(navHtml).hover( stop, start );
  82. $navBtns = $('li', $nav);
  83. $navBtns.each(function(i){
  84. $(this).bind(opts.eventNav,function(){
  85. if(isMove) return;
  86. if(numView==i) return;
  87. rollFunc(arrPos[i]);
  88. $navBtns.eq(numView).removeClass('navOn');
  89. numView = i;
  90. $(this).addClass('navOn');
  91. });
  92. });
  93. $navBtns.eq(numView).addClass('navOn');
  94. }
  95. //设定初始位置
  96. if (opts.direction == 'right' || opts.direction == 'down') {
  97. _scrollObj[_type?'scrollLeft':'scrollTop'] = scrollSize;
  98. }else{
  99. _scrollObj[_type?'scrollLeft':'scrollTop'] = 0;
  100. }
  101. if(opts.isMarquee){
  102. //滚动开始
  103. //marqueeId = setInterval(scrollFunc, opts.scrollDelay);
  104. marqueeId = setTimeout(scrollFunc, opts.scrollDelay);
  105. //鼠标划过停止滚动
  106. $marquee.hover(
  107. function(){
  108. clearInterval(marqueeId);
  109. },
  110. function(){
  111. //marqueeId = setInterval(scrollFunc, opts.scrollDelay);
  112. clearInterval(marqueeId);
  113. marqueeId = setTimeout(scrollFunc, opts.scrollDelay);
  114. }
  115. );
  116. //控制加速运动
  117. if(opts.controlBtn){
  118. $.each(opts.controlBtn, function(i,val){
  119. $(val).bind(opts.eventA,function(){
  120. opts.direction = i;
  121. opts.oldAmount = opts.scrollAmount;
  122. opts.scrollAmount = opts.newAmount;
  123. }).bind(opts.eventB,function(){
  124. opts.scrollAmount = opts.oldAmount;
  125. });
  126. });
  127. }
  128. }else{
  129. if(opts.isAuto){
  130. //轮换开始
  131. start();
  132. //鼠标划过停止轮换
  133. $marquee.hover( stop, start );
  134. }
  135. //控制前后走
  136. if(opts.btnGo){
  137. $.each(opts.btnGo, function(i,val){
  138. $(val).bind(opts.eventGo,function(){
  139. if(isMove == true) return;
  140. opts.direction = i;
  141. rollFunc();
  142. if (opts.isAuto) {
  143. stop();
  144. start();
  145. }
  146. });
  147. });
  148. }
  149. }
  150. function scrollFunc(){
  151. var _dir = (opts.direction == 'left' || opts.direction == 'right') ? 'scrollLeft':'scrollTop';
  152. if(opts.isMarquee){
  153. if (opts.loop > 0) {
  154. numMoved+=opts.scrollAmount;
  155. if(numMoved>scrollSize*opts.loop){
  156. _scrollObj[_dir] = 0;
  157. return clearInterval(marqueeId);
  158. }
  159. }
  160. var newPos = _scrollObj[_dir]+(opts.direction == 'left' || opts.direction == 'up'?1:-1)*opts.scrollAmount;
  161. }else{
  162. if(opts.duration){
  163. if(t++<d){
  164. isMove = true;
  165. var newPos = Math.ceil(easeOutQuad(t,b,c,d));
  166. if(t==d){
  167. newPos = e;
  168. }
  169. }else{
  170. newPos = e;
  171. clearInterval(scrollId);
  172. isMove = false;
  173. return;
  174. }
  175. }else{
  176. var newPos = e;
  177. clearInterval(scrollId);
  178. }
  179. }
  180. if(opts.direction == 'left' || opts.direction == 'up'){
  181. if(newPos>=scrollSize){
  182. newPos-=scrollSize;
  183. }
  184. }else{
  185. if(newPos<=0){
  186. newPos+=scrollSize;
  187. }
  188. }
  189. _scrollObj[_dir] = newPos;
  190. if(opts.isMarquee){
  191. marqueeId = setTimeout(scrollFunc, opts.scrollDelay);
  192. }else if(t<d){
  193. if(scrollId) clearTimeout(scrollId);
  194. scrollId = setTimeout(scrollFunc, opts.scrollDelay);
  195. }else{
  196. isMove = false;
  197. }
  198. };
  199. function rollFunc(pPos){
  200. isMove = true;
  201. var _dir = (opts.direction == 'left' || opts.direction == 'right') ? 'scrollLeft':'scrollTop';
  202. var _neg = opts.direction == 'left' || opts.direction == 'up'?1:-1;
  203. numRoll = numRoll +_neg;
  204. //得到当前所看元素序号并改变导航CSS
  205. if(pPos == undefined&&opts.navId){
  206. $navBtns.eq(numView).removeClass('navOn');
  207. numView +=_neg;
  208. if(numView>=_len){
  209. numView = 0;
  210. }else if(numView<0){
  211. numView = _len-1;
  212. }
  213. $navBtns.eq(numView).addClass('navOn');
  214. numRoll = numView;
  215. }
  216. var _temp = numRoll<0?scrollSize:0;
  217. t=0;
  218. b=_scrollObj[_dir];
  219. //c=(pPos != undefined)?pPos:_neg*opts.distance;
  220. e=(pPos != undefined)?pPos:_temp+(opts.distance*numRoll)%scrollSize;
  221. if(_neg==1){
  222. if(e>b){
  223. c = e-b;
  224. }else{
  225. c = e+scrollSize -b;
  226. }
  227. }else{
  228. if(e>b){
  229. c =e-scrollSize-b;
  230. }else{
  231. c = e-b;
  232. }
  233. }
  234. d=opts.duration;
  235. //scrollId = setInterval(scrollFunc, opts.scrollDelay);
  236. if(scrollId) clearTimeout(scrollId);
  237. scrollId = setTimeout(scrollFunc, opts.scrollDelay);
  238. }
  239. function start(){
  240. rollId = setInterval(function(){
  241. rollFunc();
  242. }, opts.time*1000);
  243. }
  244. function stop(){
  245. clearInterval(rollId);
  246. }
  247. function easeOutQuad(t,b,c,d){
  248. return -c *(t/=d)*(t-2) + b;
  249. }
  250. function easeOutQuint(t,b,c,d){
  251. return c*((t=t/d-1)*t*t*t*t + 1) + b;
  252. }
  253. });
  254. };
  255. $.fn.kxbdSuperMarquee.defaults = {
  256. isMarquee:false,//是否为Marquee
  257. isEqual:true,//所有滚动的元素长宽是否相等,true,false
  258. loop: 0,//循环滚动次数,0时无限
  259. newAmount:3,//加速滚动的步长
  260. eventA:'mousedown',//鼠标事件,加速
  261. eventB:'mouseup',//鼠标事件,原速
  262. isAuto:true,//是否自动轮换
  263. time:5,//停顿时间,单位为秒
  264. duration:50,//缓动效果,单次移动时间,越小速度越快,为0时无缓动效果
  265. eventGo:'click', //鼠标事件,向前向后走
  266. direction: 'left',//滚动方向,'left','right','up','down'
  267. scrollAmount:1,//步长
  268. scrollDelay:10,//时长
  269. eventNav:'click'//导航事件
  270. };
  271. $.fn.kxbdSuperMarquee.setDefaults = function(settings) {
  272. $.extend( $.fn.kxbdSuperMarquee.defaults, settings );
  273. };
  274. })(jQuery);