jQuery插件开发之boxScroll与marquee
BoxScroll
常见图片轮播效果的简单实现。可以数字列表控制或者左右按键控制。逻辑很简单,下面的Marquee形成环,这个到了尽头得往回跑,看看注释就知道了。
图片轮播GitHub:https://github.com/codetker/myBoxScroll。具体演示:http://www.梦萦无双.xyz/myBoxScroll/demo/Default.html。
插件效果:
实现常见的盒子图片滚动效果(或称图片轮播)
可修改后附加缓动函数,实现多种效果,详情见缓动函数表 http://easings.net/zh-cn#easeInOutQuad
Github https://github.com/codetker/TokenFamily
注:使用scroll-left或scroll-top的时候值只能是正数,内层必须宽度或者高度大于外层以实现scroll效果。使用margin时直接移动ul窗口来实现里面li的显示,可以在两端添加特殊效果(margin允许负值)。
html 结构(ZenCoding形式)
-div.divClass
-div.toLeft
-div.toRight
-ul.ulClass
-li.liClass*n
-ul.controlUl
-li*n
其中div.toLeft,div.toRight,ul.controlUl可选
调用方法(详情见demo)(按需设置参数)
A.divClass调用时style为1,采用scroll-left
$(".divClass").boxScroll({ 'liHover': 'liSelected', //设置控制滚动的类名 'child': 'li', //实际移动元素,默认为li元素 'style': 1, //默认为0,为margin-left,1则为scroll-left 'stepTime': 1, //每次运动经历的时间,单位s,默认为1s 'direction': 'right', //运动的方向,默认为right 'toLeft': '.arrowLeft', //向左运动按钮,默认为null 'toRight': '.arrowRight', //向右运动按钮,默认为null 'ControlUl': '.picControl ul', //控制运动按钮,默认为null 'circle': true, //是否自动滚动,默认true 'circleTime': 5 //自动滚动时间间隔,默认5s });
B.ulClass调用时style为0,采用margin-left
$(".ulClass").boxScroll({ 'liHover': 'liSelected', //设置控制滚动的类名 'child': 'li', //实际移动元素,默认为li元素 'style': 0, //默认为0,为margin-left 'stepTime': 1, //每次运动经历的时间,单位s,默认为1s 'direction': 'right', //运动的方向,默认为right 'toLeft': '.arrowLeft', //向左运动按钮,默认为null 'toRight': '.arrowRight', //向右运动按钮,默认为null 'ControlUl': '.picControl ul', //控制运动按钮,默认为null 'circle': true, //是否自动滚动,默认true 'circleTime': 5 //自动滚动时间间隔,默认5s });
C.div.Class or Ul.Class调用时style为1,采用fadeIn and FadeOut
$(".picInnerBox").boxScroll({ 'liHover': 'liSelected', //设置控制滚动的类名 'child': 'li', //实际变化元素,默认为li元素 'style': 2, //2为fadeIn and fadeOut 'direction': 'right', //滚动方向 'toLeft': '.arrowLeft', //向左运动按钮,默认为null,为了避免快速多次点击,设置点击间隔时间至少0.8s 'toRight': '.arrowRight', //向右运动按钮,默认为null,为了避免快速多次点击,设置点击间隔时间至少0.8s 'ControlUl': '.picControl ul', //控制运动按钮,默认为null 'circle': true, //是否自动变化,默认true 'circleTime': 5, //自动变化时间间隔,默认5s 'fadeInTime': 300, //fadeIn时间设置 'fadeOutTime': 400 //fadeOut时间设置 });
运行demo
最简单的方法为改Default.html中jquery对应script元素的src为本地的jquery(离线)或CDN中的jquery(在线),然后双击Default.html即可
或者配置myBoxScroll.jquery.json or package.json
PS:
为了使插件总大小较小、代码复用,将A,B,C三种情况集中在一起,封装为一个原型上的方法,内部依据style控制选择。
也可以改为多个方法在绑定到jquery原型上时用style判断对应执行,以减少多余变量和不必要的判断。
Demo代码如下:
HTML
<!doctype html> <html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta content="" name="keywords" /> <meta content="" name="description" /> <meta name="author" content="codetker" /> <head> <title>简易图片轮播插件</title> <link href="style/reset.css" rel="stylesheet" type="text/css"> <link href="style/style.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="../src/jquery-1.9.1.min.js"></script> <script type="text/javascript" src="../src/jquery.codetker.boxScroll.js"></script> </head> <body> <div class="wrap"> <div class="scrollBox"> <div class="picOuterBox boxStyle"> <div class="arrow arrowLeft">ToLeft</div> <div class="arrow arrowRight">ToRight</div> <ul class="picInnerBox boxStyle"> <li> <a href="" title=""> <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title=""> <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title=""> <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title=""> <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title=""> <img src="images/test.jpg" alt=""> </a> </li> </ul> </div> <div class="picControl"> <ul> <li class="liSelected">1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> </div> </div> </div> <script type="text/javascript"> $(document).ready(function() { /*$(".picOuterBox").boxScroll({ 'liHover':'liSelected', 'child': 'li', 'style': 1, 'stepTime': 1, 'direction': 'right', 'toLeft': '.arrowLeft', 'toRight': '.arrowRight', 'ControlUl': '.picControl ul', 'cicle': true, 'circleTime': 5 });*/ $(".picInnerBox").boxScroll({ 'liHover': 'liSelected', 'child': 'li', 'style': 0, 'stepTime': 1, 'direction': 'right', 'toLeft': '.arrowLeft', 'toRight': '.arrowRight', 'ControlUl': '.picControl ul', 'circle': true, 'circleTime': 5 }); /*$(".picInnerBox").boxScroll({ 'liHover': 'liSelected', 'child': 'li', 'style': 2, 'direction': 'right', 'toLeft': '.arrowLeft', 'toRight': '.arrowRight', 'ControlUl': '.picControl ul', 'circle': true, 'circleTime': 5, 'fadeInTime': 300, 'fadeOutTime': 400 });*/ }); </script> </body> </html>
CSS
@charset "utf-8"; /* CSS Document */ /* to make it better to see */ /* as whole */ body{ margin : 0 0; padding: 0 0; height : 100%; width : 100%; } .wrap{ font-family: "微软雅黑","宋体", Times, "Times New Roman", serif; font-size : 14px; margin : 0 0; padding : 0 0; height : 100%; width : 100%; overflow : hidden; } /* as whole end */ /* innerBox */ .boxStyle{ width : 500px; height: 256px; } .scrollBox{ position: relative; width : 500px; margin : 0 auto; } .picInnerBox{ width : 10000px; overflow: hidden; } .picInnerBox li{ cursor: pointer; float : left; } .picOuterBox{ overflow: hidden; } /* innerBox end */ /* arrow */ .arrow{ position: absolute; top : 45%; height : 40px; cursor : pointer; z-index : 99; } .arrow:hover{ color : #fff; } .arrowLeft{ float : left; left : 5%; } .arrowRight{ float: right; right: 5%; } /* arrow end */ /* controlUl */ .picControl{ overflow: auto; width : 156px; margin : 10px auto 0 auto; } .picControl ul li{ cursor : pointer; float : left; margin-left: 10px; width : 20px; height : 20px; text-align : center; -webkit-border-radius: 50%; -moz-border-radius : 50%; -ms-border-radius : 50%; -o-border-radius : 50%; border-radius : 50%; /* if <IE7,use PIE.htc or IE-css3.htc here */ } .picControl ul li:not(.liSelected){ background-color: #ccc; } .picControl ul li:hover{ background-color: #888; } .liSelected{ background-color: #888; } /* controlUl end */
JavaScript
/* * boxScroll 0.1 * 兼容FF,Chrome等常见浏览器 */ ;(function($, window, document, undefined) { //定义构造函数 var BoxObj = function(ele, opt) { this.$element = ele; this.defaults = { 'child': 'li', 'style': 0, 'stepTime': 1, 'direction': 'right', 'toLeft': null, 'toRight': null, 'ControlUl': null, 'circle': true, 'circleTime': 5, 'fadeInTime': 300, 'fadeOutTime': 400, 'liHover': null }; this.options = $.extend({}, this.defaults, opt); }; //在原型上添加方法 BoxObj.prototype = { boxScroll: function() { var boxWindow = this.$element, child = $(boxWindow).find(this.options.child), style = this.options.style, circle = this.options.circle, circleTime = this.options.circleTime, direction = (this.options.direction == 'right') ? 1 : -1, toLeft = this.options.toLeft, toRight = this.options.toRight, Control = this.options.ControlUl, liHover = this.options.liHover, lists = $(Control).children('li'), boxWidth = $(child).width(), imgIndexMax = $(child).length, imgIndex, timer, //margin and scroll stepTime stepTime = this.options.stepTime, //fadeIn and Out control time fadeInTime = this.options.fadeInTime, fadeOutTime = this.options.fadeOutTime, startTime, endTime; //判断当前图片的位置 function getImgIndex() { switch (style) { case 0: //margin imgIndex = Math.round(parseInt($(boxWindow).css('margin-left')) * (-1) / boxWidth); break; case 1: //scroll imgIndex = Math.round($(boxWindow).scrollLeft() / boxWidth); break; case 2: //fade imgIndex = getIndexShow(); break; default: } } //fade 中判断图片index function getIndexShow() { var temp; $(lists).each(function() { if ($(this).hasClass(liHover)) { temp = $(this).index(); } }); return temp; } //设置循环 function set() { if (circle) { timer = setInterval(function() { boxScroll(imgIndex, direction); }, 1000 * circleTime); } } //取消循环 function rest() { clearInterval(timer); set(); } //初始化 if (style == 2) { $(child).eq(0).click(); } set(); startTime = Date.parse(new Date()); endTime = Date.parse(new Date()); //绑定点击按钮 $(Control).delegate('li', 'click', function() { boxScroll($(this).index(), 0); rest(); }); //绑定左右按钮 $(toLeft).click(function() { //主要用于防止show and hide 左右点击过快 startTime = Date.parse(new Date()); if ((startTime - endTime) > 800) { boxScroll(0, -1); rest(); endTime = Date.parse(new Date()); } }); $(toRight).click(function() { startTime = Date.parse(new Date()); if ((startTime - endTime) > 800) { boxScroll(0, 1); rest(); endTime = Date.parse(new Date()); } }); function boxScroll(index, dir) { if (!$(boxWindow).is(':animated')) { //响应ul li control操作 if (!dir) { imgIndex = index; //响应toLeft和toRight } else { if (dir == 1) { //向右 getImgIndex(); if (imgIndex === (imgIndexMax - 1)) { imgIndex = 0; } else { imgIndex += 1; } } else { //向左 getImgIndex(); if (imgIndex === 0) { imgIndex = (imgIndexMax - 1); } else { imgIndex -= 1; } } } lists.eq(imgIndex).addClass(liHover); lists.eq(imgIndex).siblings().removeClass(liHover); //具体执行 switch (style) { case 0: $(boxWindow).animate({ 'margin-left': imgIndex * boxWidth * (-1) + 'px' }, 1000 * stepTime); break; case 1: $(boxWindow).animate({ 'scrollLeft': imgIndex * boxWidth + 'px' }, 1000 * stepTime); break; case 2: $(child).fadeOut(fadeOutTime); $(child).eq(imgIndex).fadeIn(fadeInTime); break; default: } } } } }; //将方法添加到jquery对象的原型上 $.fn.boxScroll = function(options) { //创建实例 var boxObj = new BoxObj(this, options); return boxObj.boxScroll(); }; })(jQuery, window, document);
BoxScroll1.0版本终于面世咯,希望大家尝试使用,多提issues,谢谢!
Marquee
模仿IE下面的marquee效果,鼠标移上去暂停。形成环的主要原理在于每张图片一旦判断出了外面的显示窗口就添加到尾部,用append和prepend模拟数组的push()和shift()。
代码如下:
HTML
<!doctype html> <html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta content="" name="keywords" /> <meta content="" name="description" /> <meta name="author" content="codetker" /> <head> <title>模拟marquee标签效果的简单实现</title> <link href="style/reset.css" rel="stylesheet" type="text/css"> <link href="style/style.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="js/jquery-1.9.1.min.js"></script> <script type="text/javascript" src="js/jquery.codetker.marquee.js"></script> </head> <body> <div class="wrap"> <div class="marquee"> <ul> <li> <a href="" title="">1 <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title="">2 <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title="">3 <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title="">4 <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title="">5 <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title="">6 <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title="">7 <img src="images/test.jpg" alt=""> </a> </li> <li> <a href="" title="">8 <img src="images/test.jpg" alt=""> </a> </li> </ul> </div> </div> <script type="text/javascript"> $(document).ready(function(){ $(".marquee").marquee(); }); </script> </body> </html>
CSS
@charset "utf-8"; /* CSS Document */ body{ margin:0 0; padding:0 0; height:100%; width:100%; } .wrap{ font-family:"微软雅黑","宋体", Times, "Times New Roman", serif; font-size:14px; margin:0 0; padding:0 0; height:100%; width:100%; overflow:hidden; } .marquee{ margin: 0 auto; width: 960px; height: 300px; overflow: hidden; } .marquee ul{ width: 10000px; } .marquee ul li{ float: left; width: 500px; text-align: center; } .marquee ul li a{ } .marquee ul li a:hover{ color: red; }
JavaScript
/* * boxScroll 0.1 * 兼容IE8,FF,Chrome等常见浏览器 */ ;(function($,window,document,undefined){ //定义构造函数 var BoxObj=function(ele,opt){ this.$element=ele; //最外层对象 this.defaults={ 'style': 0 ,//滚动样式选择,默认为普通效果 'speed': 1 ,//默认为1s 'direction': 'left'//默认为向左边滚动 }, this.options=$.extend({},this.defaults,opt ); //这里可以添加一些通用方法 } //给构造函数添加方法 BoxObj.prototype={ commonScroll:function(){ //接收对象属性 var obj=this.$element; var boxWindow=$(this.$element).children('ul'); var speed=this.defaults.speed; var style=this.defaults.style; var direction=(this.defaults.direction=='left')? 1 : -1; var lists=$(boxWindow).children('li'); var len=$(lists).length; var boxWidth=$(lists[0]).width(); var timer; var step=(this.defaults.direction=='left')? 0 : boxWidth; function move(style,speed,direction){ if (style==0) { if (direction==1) { step+=1; if(step>boxWidth){ step-=boxWidth; $(boxWindow).append($(boxWindow).children().eq(0));//将第一项放在最后,相当于push(0),shift() }else{ $(obj).scrollLeft(step); } }else if (direction== -1) { step-=1; if(step<0){ step+=boxWidth; $(boxWindow).prepend($(boxWindow).children().eq(len-1));//将最后一项放在最前,相当于pop(last),unshift() }else{ $(obj).scrollLeft(step); } }else{//不执行之外的数值 } }else{//留待扩展,多了改switch } } timer=setInterval(function(){ move(style,speed,direction); },10*speed); //由于时间取得小,肉眼就看不出来 $(lists).each(function() {//鼠标移上暂停 $(this).hover(function() { clearInterval(timer); }, function() { clearInterval(timer); timer=setInterval(function(){ move(style,speed,direction); },10*speed); }); }); } } $.fn.marquee=function(options){ //创建实体 var boxObj=new BoxObj(this,options); //用尾调的形式调用对象方法 return boxObj.commonScroll(); } })(jQuery,window,document);
详细下载见https://github.com/codetker/myMarquee