/**
* @author '陈桦'
* @date '2016-5-10'
* @description 滑动轮播插件,支持水平和垂直方向滑动轮播
*
* @example
html:
body,ul,ol{margin: 0; padding: 0;}
ul,ol{list-style: none;}
.li1{background-color: #000;}
.li2{background-color: #333;}
.li3{background-color: #666;}
.li4{background-color: #999;}
.example{margin-left: 300px;}
.example ol {
position: absolute;
padding-left: 80px;
width: 186px;
height: 20px;
top: 186px;
left: 0px;
background: #fff;
cursor: pointer;
}
ol li{
float: left;
width: 10px;
height: 10px;
margin: 5px;
background: #ff0;
border-radius: 10px;
}
ol li.circle{
background: #f00;
}
js:
$('.example').nfdscroll({
startIndex:0,
width:'266',
height:'216',
interval:2000,
selected:'circle',
prevText:'上一个',
nextText:'下一个',
deriction:'left',
callback: function(index,$currentNode){
console.log(index)
}
});
* @example end
* @param startIndex {Number} 默认从第几个滚动体开始滚动,可选(0-n,0表示第一个,默认为0)
* @param width {Number} 滚动体宽度,可选(当宽度为0时表示不设置宽度)
* @param height {Number} 滚动体高度,可选(当高度为0时表示不设置高度)
* @param interval {Number} 间隔时间,单位毫秒, 当值为负时表示不进行自动滚动
* @param duration {Number} 动画持续时间
* @param selected {String} 滚动切换小图标(焦点列表)当前class
* @param deriction {String} 滚动方向,支持left/right和top/bottom
* @param callback {Function} 滑动动画结束时触发的回调,参数(index,$currentNode),index:轮播结束后展示的节点的索引;currentNode:轮播结束后当前展示的节点的jquery对象
* @param prevText {String} 上一个按钮的文本,默认是"上一个"
* @param nextText {String} 下一个按钮的文本,默认是"下一个"*/jQuery.fn.extend({
nfdscroll:function(options) {var defaultOpt ={
startIndex:0,
width:0, //滚动体宽度,可选(当宽度为0时表示不设置宽度)
height: 0, //滚动体高度,可选(当高度为0时表示不设置高度度)
interval: 1000, //间隔时间毫秒
duration: 400, //动画持续时间
selected: 'selected', //滚动切换小图标当前class
prevText: '上一个',
nextText:'下一个',
deriction:'left', //滚动方向
callback: function(index, $currentNode) { //每次滚动到新节点后马上触发,currentNode是当前展示的节点的jquery对象
}
},
$this = this,
$panel= $this.find('>ul'), //滚动容器
$panelList = $panel.find('>li'),
$selectList= $this.find('>ol>li'), //选择容器
options =jQuery.extend(defaultOpt, options),
animateFn,//滚动动画
max = $panel.find(">li").length, //要滚动的节点的数量
focusIndex = 0, //当前展示的节点的索引
nfdscrollTimer = 0, //计时器
inAnimation = false, //动画过程中不再响应其他动画
isWaitting = false, //是否有未执行的等待动画
waittingIndex; //未执行的等待动画的目标index
$this.find('.nfdscroll-prev').text(options.prevText);
$this.find('.nfdscroll-next').text(options.nextText);//只有一个展示,不需要轮播
if ($panelList.length <= 1) {return;
}//当前动画没有做完但是焦点已经切换到下一个地方,这个函数就是用来执行保障当前显示的页面和鼠标指定的目标一致的处理
functiondoWaitting() {if(isWaitting) {
startScroll(waittingIndex);
}
}//开始轮播
functionstartScroll(toIndex) {
stopScroll();if(inAnimation) {
isWaitting= true;
waittingIndex=toIndex;return; //动画过程中不再响应其他动画
} else{
isWaitting= false;
}if (toIndex ==undefined) {if (options.interval > 0) {
nfdscrollTimer= setInterval(function() {
animateFn(toIndex);
}, options.interval);
}//跳到指定index后再计时
} else{
animateFn(toIndex);if (options.interval > 0) {
nfdscrollTimer= setInterval(function() {
animateFn();
}, options.interval);
}
}
}//停止轮播
functionstopScroll() {
clearInterval(nfdscrollTimer);
}//向左向右滚动动画
//参数toIndex: number,滚动到指定index
functionleftRightAnimate(toIndex) {//默认滚动方式
if (toIndex ==undefined) {if (options.deriction == 'left') {
toIndex= focusIndex + 1;
}else{
toIndex= focusIndex - 1;
}
}if (toIndex !=focusIndex) {
inAnimation= true;//当前为最后一个轮播体时的处理
var tInd = 0;if (toIndex >= max) { //最后一张图片继续滚动时
$panel.css({'paddingLeft': options.width + 'px'})
$panelList.eq(0).css({'position': 'absolute','left': options.width * toIndex + 'px'});
tInd= 0;
}else if (toIndex < 0) { //仅仅在当前图片是第一个图片,然后点击上一个图片的时候出现
//当前为最后一个轮播体时的处理
$panelList.eq(max - 1).css({'position': 'absolute','left': -options.width + 'px'});
tInd= max - 1;
}else{
tInd=toIndex;
}//先将焦点切换过去
$selectList.filter('.' +options.selected).removeClass(options.selected)
.end().eq(tInd).addClass(options.selected);
$panel.animate({'marginLeft': -options.width * toIndex + 'px'}, options.duration,function() {
focusIndex=tInd;if (toIndex >= max) { //最后一张图片继续滚动时
$panel.css({'marginLeft': 0,'paddingLeft': 0});
$panelList.eq(0).css({'position': 'static','left': 'auto'});
}else if (toIndex < 0) { //仅仅在当前图片是第一个图片,然后点击上一个图片的时候出现
$panel.css({'marginLeft': -options.width * focusIndex + 'px','paddingLeft': 0});
$panelList.eq(max- 1).css({'position': 'static','left': 'auto'});
}
options.callback(focusIndex, $panelList.eq(focusIndex));
inAnimation= false;
doWaitting();
})
}
}//向上向下滚动动画
functiontopBottomAnimate(toIndex) {//默认滚动方式
if (toIndex ==undefined) {if (options.deriction == 'top') {
toIndex= focusIndex + 1;
}else{
toIndex= focusIndex - 1;
}
}if (toIndex !=focusIndex) {
inAnimation= true;//当前为最后一个轮播体时的处理
var tInd = 0;if (toIndex >=max) {
$panel.css({'paddingTop': options.height + 'px'})
$panelList.eq(0).css({'position': 'absolute','top': options.height * toIndex + 'px'});
tInd= 0;
}else if (toIndex < 0) { //仅仅在当前图片是第一个图片,然后点击上一个图片的时候出现
//当前为最后一个轮播体时的处理
$panelList.eq(max - 1).css({'position': 'absolute','top': -options.height + 'px'});
tInd= max - 1;
}else{
tInd=toIndex;
}//先将焦点切换过去
$selectList.filter('.' +options.selected).removeClass(options.selected)
.end().eq(tInd).addClass(options.selected);
$panel.animate({'marginTop': -options.height * toIndex + 'px'}, options.duration,function() {
focusIndex=tInd;if (toIndex >=max) {
$panel.css({
marginTop:0,'paddingTop': 0});
$panelList.eq(0).css({'position': 'static','top': 'auto'});
}else if (toIndex < 0) { //仅仅在当前图片是第一个图片,然后点击上一个图片的时候出现
$panel.css({'marginTop': -options.height * focusIndex + 'px','paddingTop': 0});
$panelList.eq(max- 1).css({'position': 'static','top': 'auto'});
}
options.callback(focusIndex, $panelList.eq(focusIndex));
inAnimation= false;
doWaitting();
})
}
}functionbindEvent() {//绑定事件
$this.on('mouseover', function() {
stopScroll();
}).on('mouseout', function() {
startScroll();
}).on('click', '.nfdscroll-prev', function() {
stopScroll();
startScroll(focusIndex- 1);
}).on('click', '.nfdscroll-next', function() {
stopScroll();
startScroll(focusIndex+ 1);
})
$selectList.on('mouseover', function() {
stopScroll();if (!$(this).is('.' +options.selected)) {
startScroll($(this).index());
}
});
}functioninit() {
$this.css({
position:'relative',
overflow:'hidden'});
$panel.css({
position:'relative'})
focusIndex= options.startIndex; //默认从startIndex开始滚动
$selectList.eq(focusIndex).addClass(options.selected); //先将焦点切换过去
if (options.deriction == 'left' || options.deriction == 'right') {//初始化样式,实际上不应该插件里面来做样式,应该使用者自己就保证样式没有问题
var cssO ={
width: options.width,'float': 'left'}
$this.css({
width: options.width
});//只需要管宽度即可
if(options.height) {
cssO.height=options.height;
}var leng = $panel.find('>li').css(cssO).length;
$panel.css({
width: options.width* leng + 'px','marginLeft': -options.width * focusIndex + 'px'});
animateFn=leftRightAnimate;
}else if (options.deriction == 'top' || options.deriction == 'bottom') {var cssO ={
height: options.height
}
$this.css({
height: options.height
});//只需要管高度度即可
if(options.width) {
cssO.width=options.width;
}var leng = $panel.find('>li').css(cssO).length;
$panel.css({
height: options.height* leng + 'px','marginTop': -options.height * focusIndex + 'px'});
animateFn=topBottomAnimate;
}else{
alert('插件只支持left/right/top/bottom四种方向上的滚动');return;
}
startScroll();
}
bindEvent();
init();return{'stopScroll': stopScroll,'startScroll': startScroll
}
}
});