前言
项目才是最大的驱动力!最近又做一个页面,里面出现了大量的轮播图,如果一个一个写的话,那js工作量简直不敢想。个人比较懒,就自己试着封装了一个超级简陋的插件(只能用来控制DOM的行为,各元素的css样式还是需要在css内定义)。开发过程参考了 慕课网——js实现旋转木马 中插件的结构。代码如下:
创建此插件采用的方式: 组合使用构造函数和原型模式(js红宝书p159)
;(function($){
var Carousel = function(poster){
var self = this;
this.poster = poster;
this.posterItemMain = poster.find("ul.carousel-list");
this.postersItems = poster.find(".carousel-list>li");
this.prevBtn = poster.find(".control-prev");
this.nextBtn = poster.find(".control-next");
this.controlDot = poster.find(".pager");
this.flag = 0;
this.slideLeft =0;
this.trunDir = true; //用于控制自动播放时,方向的改变
this.len = this.postersItems.length; //需要移动的li 的总数
this.ulW = this.posterItemMain.width(); //需要移动的总宽度----ul 的宽
this.wrapperW = poster.find(".carousel-wrapper").width(); //显示的宽度------wrapper 的宽
this.MaxFlag = Math.floor(this.ulW / this.wrapperW);
this.slideLength = this.ulW / this.MaxFlag; //每次移动的单位长度
console.log(this.len);
console.log(this.ulW);
console.log(this.wrapperW);
console.log(this.MaxFlag);
console.log(this.slideLength);
console.log("_____________________________");
//默认参数设置, 当然了,这些根据需求都是可以扩展的啦
this.setting = {
"autoPlay": false, //是否自动播放
"delay": "5000" //自动播放间隔时间
};
//合并对象,覆盖默认参数。默认参数设置在应用此插件的 data-setting 自定义属性中,简单好使,可以为每个对象设置不同的参数
$.extend(this.setting, this.getSetting());
this.prevBtn.click(function(){
self.carouselRotate("left");
});
this.nextBtn.click(function(){
self.carouselRotate("right");
});
//页面对应按钮点击事件
this.controlDot.click(function(){
self.flag = $(this).index();
self.slideLeft = "-"+self.flag*self.slideLength;
$(this).addClass("pager-active").siblings().removeClass("pager-active");
self.posterItemMain.css("margin-left", self.slideLeft+"px");
});
//是否开启自动播放
if(this.setting.autoPlay) {
this.autoPlay(this.setting.delay);
}
};
Carousel.prototype = {
//自动播放
autoPlay: function(delay){
var self = this;
window.setInterval(function(){
self.autoPlayPre();
}, delay);
},
autoPlayPre: function(){
if(this.trunDir) {
this.carouselRotate("right");
} else {
this.carouselRotate("left");
}
},
//左右轮播
carouselRotate: function(dir){
if(dir === "left") {
if(this.flag == 0) {
this.trunDir = true;
return false;
}
else if (this.flag > 0) {
this.flag--;
this.slideLeft -= "-"+this.slideLength; //点击dot后 如果 += 结果是字符串
this.nextBtn.removeClass("control-disabled");
if(this.flag == 0) {
this.prevBtn.addClass("control-disabled");
}
}
}
if(dir === "right") {
if(this.flag == this.MaxFlag-1) {
this.trunDir = false;
return false;
}
else if (this.flag < this.MaxFlag-1) {
this.flag++;
this.slideLeft -= this.slideLength;
this.prevBtn.removeClass("control-disabled");
if(this.flag == this.MaxFlag-1) {
this.nextBtn.addClass("control-disabled");
}
}
}
//alert(typeof this.slideLeft);
this.posterItemMain.css("margin-left", this.slideLeft+"px");
this.controlDot.eq(this.flag).addClass("pager-active").siblings().removeClass("pager-active");
},
//获取人工配置参数
getSetting: function(){
var setting = this.poster.attr("data-setting");
if(setting && setting != "") {
return $.parseJSON(setting);
} else {
return false;
}
}
};
//可以为每个jQuery对象创建各自的对象属性及方法
Carousel.init = function(posters){
var _this_ = this;
posters.each(function(){
new _this_($(this));
});
};
//将Carousel 全局注册到 window上,使它成为一个方法
window["Carousel"] = Carousel;
})(jQuery);
备注:
1、利用匿名函数自执行的方式封装类,并将jQuery作为参数传递进去,防止引用多个js库造成命名冲突
;(function($){
//代码段.........
})(jQuery);
2、使用, 传入一个jquery对象即可,通常习惯将需要用到此插件的DOM元素统一添加一个 classname, 如 .J_####
<script>
Carousel.init($(".J_Carousel"));
</script>
3、可完善的(暂时想起这么多)
①根据需要轮播元素多少自动生成 pagerControlBtn 小圆点按钮
②控制小圆点按钮的位置(意义不大)