jQuery幻灯片插件开发
憋了N天,终于整出来个jQuery的幻灯片插件。jQuery的插件资源非常丰富(25个必须学会的jQuery幻灯片插件教程),没有必要重复发明轮子,任务需要或技能训练,必要的时候还是要动手去做一下,有利于提高JS能力。
先来看一下如何使用该插件,知道如何使用jQuery访问DOM,就可以轻松使用该插件。当然要先从HTML结构开始出发。
HTML代码
<div id="ad_gallery">
<div class="ad_sheet_wrap">
<ul class="ad_sheet_con">
<li><a href="#"><img src="image/image_1.jpg"></a></li>
<li><a href="#"><img src="image/image_2.jpg"></a></li>
<li><a href="#"><img src="image/image_3.jpg"></a></li>
<li><a href="#"><img src="image/image_4.jpg"></a></li>
<li><a href="#"><img src="image/image_5.jpg"></a></li>
</ul>
</div>
</div>
这是幻灯片所必须的HTML结构,默认自动切换,如果感觉不简洁,那也没办法了。.ad_sheet_wrap和.ad_sheet_con是默认的类名,如果想要改变它的名字,可以在调用插件的时候以参数的形式传递过去。
CSS代码
* {margin:0; padding: 0;}
ul {list-style-type: none;font-size: 0;}
img {border: 0;}
.ad_sheet_wrap {width:514px; height:191px; overflow:hidden; position:relative;}
.ad_sheet_con {position: absolute;}
样式代码一样如此简洁,主要涉及基础的定位知识。需要注意的是,在IE6、7中,上下滚动是,li标签会出现几个像素的空白。详情请参考无序列表ul在IE6,IE7出现的下边距BUG。
JavaScript代码
jQuery('#ad_gallery').adGallery();
如何导入jQuery库和插件库就不说了,估计应该都知道,以上是最简洁的幻灯片模式,可以查看效果图。
如果要获得其它的附加效果,可以提供相对应的参数。详细参数如下。
options = {
startIndex: 0, // 默认从第一张图片开始
autoPlay: true, // 自动播放
duration: 5000, // 5秒切换一次
direction: "top", // 默认垂直,可用left
event: "mouseover", // 切换触发事件
sheet: 'img', // 幻灯片外层元素
thumb: 'span', // 触发器外层元素
thumbNav: false, // 是否显示数字切换按钮
adNav: false, // 是否显示前一张、后一张按钮
sheetWrap: '.ad_sheet_wrap', // 幻灯片容器
thumbWrap: '.ad_thumb_wrap', // 触发器容器
sheetCon: '.ad_sheet_con', // 幻灯片包裹层
}
以上是基本的使用方式。感觉没有什么难理解的地方。如果遇到问题或有疑问,请给我留言。
下面讲解一下开发该插件的思路。
jQuery一般获取页面DOM对象,将其转换成jQuery对象,该对象就能访问jQuery提供的所有方法。可以扩展jQuery对象本身,将开发的插件绑定到jQuery对象上,但这样就无法使用 jQuery里最强大的链式调用了。jQuery提供了一个插件扩展接口(jQuery.fn),可以在该接口上扩展jQuery类。
// 扩展jQuery对象本身
$.adGallery = function(adGalleryCon, options) { }
// 扩展jQuery提供的插件接口
$.fn.adGallery = function(options) {
return this.each(function() {
$(this).data('adGallery', new $.adGallery(this, options));
});
}
基本的jQuery扩展方式一般就这两种,而且最常用的是两者混用,提供多种选择。
幻灯片一般通过控制HTML元素的left或者top属性来移动、切换幻灯片容器。下面的图片是Chrome浏览器运行时的HTML结构的截图。
从最简单的开始出发,幻灯片需要什么,也就是在规律的时间内切换幻灯展示。这是我认为的最基本的功能,其它的都是在此基础上进行扩展。数字触发器,上一张、下一张导航,都属于可选的功能之列。
从HTML结构上来说,要求并不是太多,必须按照插件提供的类名或者自定义变量来创建HTML结构。下面是基本的HTML结构。
<div class="ad_gallery">
<div class="ad_sheet_wrap">
<div class="ad_sheet_con">
......
</div>
</div>
<div class="ad_thumb_wrap">
....
</div>
</div
如何自定义自己的类名和标签,上面的默认属性里面已经提到了。需要一提的是,我认为数字触发器是可选的,并且是根据幻灯片的数量来动态添加到HTML结构中的,如果调用者自己提供了触发器,那么插件会认为调用者知道自己在做什么,会提供正确的触发器。
下面是插件的构造器
$.adGallery = function(adGalleryCon, options) {
var that = this, settings = $.extend({}, defaults, options || {}),
adCon = $(adGalleryCon),
sheetWrap = $(settings.sheetWrap, adCon),
thumbWrap = $(settings.thumbWrap, adCon);
this.adCon = adCon;
this.sheetWrap = sheetWrap;
this.thumbWrap = thumbWrap;
this.sheetCon = $(settings.sheetCon, sheetWrap);
this.sheetData = $(settings.sheet, this.sheetCon);
this.sheetWidth = 0;
this.sheetHeight = 0;
this.thumbData = [];
this.settings = settings;
this.initialize();
return this;
};
初始化取得幻灯片容器和触发器容器,获取幻灯片的数量,存放到this.sheetData数组中,初始化触发器的容器为空数组,将在程序后面进行填充,主要的初始化部分在initialize()方法中。
initialize: function() {
var settings = this.settings;
this.dir = settings.direction;
this.curIndex = settings.startIndex > this.sheetData.length ? this.sheetData.length - 1 : settings.startIndex;
this.oldIndex = 0;
this.timer = null;
this.initSheet();
this.bindHover(this.sheetWrap);
if (settings['thumbNav'] || this.thumbWrap.length) this.initThumb();
if (settings['adNav']) this.createAdNav();
if (settings['autoPlay']) this.autoPlay();
},
this.curIndex进行拦截处理,防止调用者提供超出幻灯片总数的起始数值。this.oldIndex属性存放上一次的幻灯片索引,主要为了避免触发器切换时执行for循环。
this.initSheet()用来初始化幻灯片容器。this.initThumb()用来初始化触发器。这两个部分比较重要,当然,不用触发器时后者就不重要了。
initSheet: function() {
var sheet = $(this.sheetData[0]),
sheetWidth = sheet.width() || this.sheetWrap.width(),
sheetHeight = sheet.height() || this.sheetWrap.height();
this.sheetWrap.css({"position": "relative", "overflow": "hidden", "width": sheetWidth + "px", "height": sheetHeight + "px"});
this.sheetCon.css({"position": "absolute"});
$(this.settings.sheet, this.sheetCon).css({"width": sheetWidth + "px", "height": sheetHeight + "px", "overflow": "hidden"});
if ('left' === this.dir) {
this.sheetCon.css({"width": sheetWidth * this.sheetData.length + 'px', "left": (- this.curIndex * sheetWidth) + 'px'});
$(this.settings.sheet, this.sheetCon).css({"float": "left"});
} else {
this.sheetCon.css('top', (- this.curIndex * sheetHeight) + 'px');
}
this.sheetWidth = sheetWidth;
this.sheetHeight = sheetHeight;
},
这一段程序主要对幻灯片容器进行样式修改。幻灯片的宽度和高度通过jQuery动态获取,需要注意的是,如果提供的幻灯片标签是img,图片无法及时载入,只能从父容器上获取宽和高属性。再者,如果向水平滚动,需要设置幻灯片容器的宽度以及幻灯片的float属性。
initThumb: function() {
var thumbWrap = this.thumbWrap;
if (1 === thumbWrap.length) {
this.bindThumbEvent($(this.settings.thumb, thumbWrap));
} else if (!!this.settings['thumbNav']) {
this.createThumbNav();
}
this.thumbData[this.curIndex].addClass('selected');
},
这部分程序用来初始化触发器,并且在this.bindThumbEvent()方法中将触发器压入到this.thumbData数组中,这在图片切换的时候要用到。
select: function(index) {
if (this.thumbData.length) this.selectedThumb(index);
if ('top' === this.dir) {
this.sheetCon.stop().animate({top: -index * this.sheetHeight}, 300);
} else {
this.sheetCon.stop().animate({left: -index * this.sheetWidth}, 300);
}
this.curIndex = index;
},
selectedThumb: function(index) {
var thumbData = this.thumbData;
this.oldIndex = this.curIndex;
thumbData[this.oldIndex].removeClass('selected');
thumbData[index].addClass('selected');
},
主要的部分基本上就是这些。在select方法调用的时候,对触发器进行处理。上一个触发器移除selected类,下一个添加selected类,这就是上面说过的避免for循环,这样就必须在程序中处理好索引。实现幻灯片切换的部分在select方法中,其实,不用插件感觉实现代码量更少,但是弊端就是每次都要从头开始。
现在还没有评论