jq轮播图插件

插件实现:(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"]
})

最终还是有点小问题。封装插件后,连续点击左右按钮会出现持续运动。希望有人帮解决下~

猜你喜欢

转载自blog.csdn.net/qq_35401191/article/details/81173009