插件实现:(id=swiper名的父级防止相同样式覆盖)
轮播图显示区域作为对象调用插件 ,$('#swiper')
图片路径不相同,图片数量不同arr.length(索引为length-1)
尺寸不同(width,height)
父级不同(wrapper)
立即执行函数
父级容错(没用wrap
$.fn.extend({
sliderShow: function (opstions) {
var opts = opstions;
opts.father = this || $('body')
new Swiper(opts);
}
})
extend实现插件扩展的原理,从extend的源码可以看出,当我们传入仅有一个对象时,他会把对象跟jQuer对象本身合并,使得在jQuery身上多出了我们传入的对象上的方法,这样一个过程,就是我们扩展插件的原理;
对象里面有个sliderShow方法,将会合并到 jquer.prototype上实现实例化调用
function Swiper(opts) {
this.opts = opts || {} //兼容一下,没有传对象进来也是undefined不会报错;
this.wrap = this.opts.father; //保存一下wrap,也就是谁调用,这个wrap就是谁;
this.init(); //入口函数;
}
//上方this.init()调用,这里面的所有this指向的还是new出来的那个对象;就相当于添加了一些变量跟方法;
Swiper.prototype.init = function () {
this.nowIndex = 0; //设定初始索引值
this.timer = undefined; //定义定时器的属性名
this.flag = true; //锁功能
this.len = this.opts.image.length; //获取图片数量;
this.itemWidth = this.wrap.width(); //通过父级宽度决定图片所需宽度以及位移所需宽度
this.itemHeight = this.wrap.height();
this.image = this.opts.image; //保存一下image图片数组;
this.createDom(); //创建dom结构!这样执行Swiper会在自己身上找不到这个方法,而后上原型上面找;
this.bindEvent(); //绑定点击事件;
this.sliderAuto(); //开启自动轮播;
}
//dom结构的创建
Swiper.prototype.createDom = function () {
var len = this.len;
var str = " ";
var listStr = " ";
var imgBox = $('<ul class = "img-box"></ul>'); //创建图片的ul
var list = $('<ul class="list"></ul>'); //创建索引点ul;
var btn = '<div class="btn prev"></div><div class="btn next"></div>'
//通过for循环,字符串拼接的方法创建图片dom结构;
for (var i = 0; i < len; i++) {
str += "<li><a><img src=" + this.image[i] + ' alt=""></a></li>';
listStr += '<li></li>';
}
//重新创第一张图,也就是最后一张过度图片;
str += "<li><a><img src=" + this.image[0] + ' alt=""></a></li>'
this.wrap.append(imgBox.html(str)).append($(btn)).append(list.append($(listStr)));
//链式的将创建出来的dom元素插入整个wrap,也就是谁调用,就插到哪
//注意:append是将上方创建的dom元素插入,而html是字符串,不能解析成dom结构,只能通过html写入结构;
$('li', '.list').eq(0).addClass('active'); //设置默认第一个小圆点样式;
$('.img-box').css('width', (len + 1) * this.itemWidth)
}
//点击事件处理
Swiper.prototype.bindEvent = function () {
var self = this;
//为了区分下面事件里面的this与全局的this,这里我们保存一下这个全局的this;
//绑定点击事件;
$('.prev').add('.next').add('.list li').on('click', function () {
self.flag = true;
if ($(this).attr('class') == "btn prev") {
self.move('prev');
} else if ($(this).attr('class') == "btn next") {
self.move('next');
} else {
self.move($(this).index());
}
})
self.wrap.on('mouseenter', function () {
$('.btn').show();
self.flag = false;
}).on('mouseleave', function () {
$('.btn').hide();
self.flag = true;
self.sliderAuto();
})
}
//点击事件运动
Swiper.prototype.move = function (dir) {
var self = this;
var flag = this.flag;
var itemWidth = self.itemWidth;
var len = self.len;
if (flag) {
if (dir == 'prev' || dir == 'next') {
if (dir == 'prev') {
if (self.nowIndex == 0) {
$('.img-box').css('left', -(len * itemWidth) + 'px');
self.nowIndex = len - 1;
} else {
self.nowIndex--;
}
} else {
if (self.nowIndex == len - 1) {
$('.img-box').animate({ left: -(len * itemWidth) }, function () {
$(this).css('left', '0');
self.changeStyle();
})
self.nowIndex = 0;
} else {
self.nowIndex++;
}
}
} else {
self.nowIndex = dir;
}
self.slider()
}
}
Swiper.prototype.slider = function () {
var self = this;
var flag = self.flag;
var nowIndex = self.nowIndex;
var itemWidth = self.itemWidth;
flag = false;
$('.img-box').animate({ left: -(nowIndex * itemWidth) }, function () {
self.flag = $('.btn').css('display') === 'block' ? false : true;
self.changeStyle();
self.sliderAuto();
})
}
//自动轮播
Swiper.prototype.sliderAuto = function () {
var self = this;
var flag = self.flag;
if (flag) {
clearTimeout(self.timer);
self.timer = setTimeout(function () {
self.move('next');
}, 1500)
}
}
//索引点css样式处理
Swiper.prototype.changeStyle = function () {
var self = this;
var nowIndex = self.nowIndex;
$('.active').removeClass('active');
$('.list li').eq(nowIndex).addClass('active');
}
然后用一个立即执行函数将上各个模块包裹。不污染全局
(function ($) {
//插件是实例化:sliderShow方法
$.fn.extend({
sliderShow: function (opetions) {
var opts = opetions;
opts.father = this || $('body');
new Swiper(opts);
}
})
function Swiper(opts) {
this.opts = opts || {};
this.swiper = this.opts.father;
this.init();
}
//入口函数,控制台资源分配
Swiper.prototype.init = function () {
this.nowIndex = 0;
this.timer = undefined;
this.flag = true;
this.len = this.opts.image.length;
this.picWidth = this.swiper.width();
this.picHeight = this.swiper.height();
this.image = this.opts.image;
this.createDom();
this.bindEvent();
this.sliderAuto();
}
Swiper.prototype.createDom = function () {
console.log('构建dom')
var len = this.len;
var str = " ";
var listStr = " ";
var imgBox = $('<ul class = "img-box"></ul>');
var list = $('<ul class="list"></ul>');
var btn = '<div class="btn prev"></div><div class="btn next"></div>'
for (var i = 0; i < len; i++) {
str += "<li><a><img src=" + this.image[i] + ' alt=""></a></li>';
listStr += '<li></li>';
}
str += "<li><a><img src=" + this.image[0] + ' alt=""></a></li>'
this.swiper.append(imgBox.html(str)).append($(btn)).append(list.append($(listStr)));
$('li', '.list').eq(0).addClass('active');
$('.img-box').css('width', (len + 1) * this.picWidth)
}
Swiper.prototype.bindEvent = function () {
var self = this;
var flag = self.flag;
//绑定点击事件;
$('.list li').add('.prev').add('.next').on('click', function () {
if ($(this).attr('class') == 'btn prev') {
//点击左,页面向左移
self.move('prev');
} else if ($(this).attr('class') == 'btn next') {
//点击右,页面向右移
self.move('next');
} else {
//点击索引圆点,往特定的索引切换
self.move($(this).index());
self.changeStyle()
}
})
//实际控制自动轮播
$('#swiper').on('mouseenter', function () {
$('#swiper .btn').show();
clearTimeout(self.timer);
}).on('mouseleave', function () {
$('#swiper .btn').hide();
self.sliderAuto();
})
}
Swiper.prototype.move = function (dir) {
//不能对nnowindex 进行赋值保存
var self = this;
var flag = self.flag;
var picWidth = self.picWidth;
var len = self.len;
console.log(flag, '运动判断')
if (flag) {
flag = false;//防止运动叠加
if (dir == 'prev') {
if (self.nowIndex == 0) {
$('.img-box').css('left', -len * picWidth + 'px');//缓冲跳到最后
self.nowIndex = len - 1;
} else {
self.nowIndex--;
}
} else if (dir == 'next') {
if (self.nowIndex == len - 1) {
$('.img-box').animate({ 'left': -(len * picWidth) + 'px' }, function () {
$('.img-box').css('left', '0');
})
self.nowIndex = 0;
} else {
self.nowIndex++;
}
} else {
self.nowIndex = dir;
}
self.slider();
self.changeStyle()
}
}
Swiper.prototype.slider = function () {
var self = this;
var nowIndex = self.nowIndex;
var picWidth = self.picWidth;
$('.img-box').animate({ 'left': -(nowIndex * picWidth) + 'px' }, function () {
self.flag = true;
})
}
Swiper.prototype.sliderAuto = function () {
var self = this;
console.log(self.nowIndex);
clearTimeout(self.timer);
self.timer = setTimeout(function () {
self.move('next');
self.sliderAuto();
}, 2000)
}
Swiper.prototype.changeStyle = function () {
var self = this;
var nowIndex = self.nowIndex;
$('.active').removeClass('active');
$('.list li').eq(nowIndex).addClass('active');
}
}($))
$('#swiper').sliderShow({
image:["img/1.jpg","img/2.jpg","img/3.jpg","img/4.jpg","img/5.jpg"]
})
最终还是有点小问题。封装插件后,连续点击左右按钮会出现持续运动。希望有人帮解决下~