var ps = $.extend({
renderTo: $(document.body),
enable: true,
initPosition: 'max',
size: { barWidth: 200, sliderWidth: 5 },
barCssName: 'defaultbar',
completedCssName: 'jquery-completed',
sliderCssName: 'jquery-jslider',
sliderHover: 'jquery-jslider-hover',
onChanging: function() { },
onChanged: function() { }
}, setting);
规范的做法:
复制代码 代码如下:
$.fn.jSlider.default = {
renderTo: $(document.body),
enable: true,
initPosition: 'max',
size: { barWidth: 200, sliderWidth: 5 },
barCssName: 'defaultbar',
completedCssName: 'jquery-completed',
sliderCssName: 'jquery-jslider',
sliderHover: 'jquery-jslider-hover',
onChanging: function() { },
onChanged: function() { }
};
$.extend({},$.fn.jSlider.default,setting);
ok, 下面描述下我所定义的这些API的作用:
renderTo: jSlider的载体、容器,可以是一个jQuery对象,也可以是选择器。
enable: jSlider插件是否可用,true时end-user可拖拽,否则禁止。
initPosition: jSlider的初始值,‘max'或者‘min',亦即 slider的value值,1或者0。
size: jSlider的参数,包括2个值barWidth - bar的长度, sliderWidth - slider的长度。
barCssName: bar的样式名称,便于end-user自行扩展样式。
completedCssName: completed的样式名称。
sliderCssName: slider的样式名称。
sliderHover: slider聚焦时的样式名称。
onChanging: slider被拖拽时触发的事件。
onChanged: slider拖拽结束时触发的事件。
此时我们需要将renderTo强制转换成jQuery对象(兼容使用selector的情况):
ps.renderTo = (typeof ps.renderTo == 'string' ?
$(ps.renderTo) : ps.renderTo);
然后将html tree输出到render:
/* ---------->
html tree:
复制代码 代码如下:
<div> ---->sliderbar
<div> </div> ----> completed bar
<div> </div> ----> slider
</div>
<-----------*/
var sliderbar = $('<div><div> </div><div> </div></div>')
.attr('class', ps.barCssName)
.css('width', ps.size.barWidth)
.appendTo(ps.renderTo);
var completedbar = sliderbar.find('div:eq(0)')
.attr('class', ps.completedCssName);
var slider = sliderbar.find('div:eq(1)')
.attr('class', ps.sliderCssName)
.css('width', ps.size.sliderWidth);
这样我们就在UI上直接呈现了Html并且用定制的css进行渲染,分别用sliderbar, completedbar, slider对我们需要的三个对象进行缓存。
ok, 在呈现了UI后我们就需要提供方法来实现slider的拖拽,在这之前我们还需要实现一个方法,就是completedbar的实时更新,即在拖动slider的时候让completedbar始终填充左侧区域:
复制代码 代码如下:
var bw = sliderbar.width(), sw = slider.width();
//make sure that the slider was displayed in the bar(make a limited)
ps.limited = { min: 0, max: bw - sw };
if (typeof window.$sliderProcess == 'undefined') {
window.$sliderProcess = new Function('obj1', 'obj2', 'left',
'obj1.css(\'left\',left);obj2.css(\'width\',left);');
}
$sliderProcess(slider, completedbar, eval('ps.limited.' + ps.initPosition));
bw,sw用来存储sliderbar和slider的长度,此处没有直接使用ps.size里的值是为了防止样式里的border-width对width造成破坏。
定义一个私用成员limited来存储slider[left]的最大值和最小值,并在后面直接使用eval('ps.limited.' + ps.initPosition)来获取,从而避免switch操作。
同时还需定义一个全局Function用来定位completedbar的填充长度以及slider左侧距离,我给其命名为$sliderProcess。
那么我们接下来剩下的工作就是slider的拖拽功能了,那么在这里我会用到之前发布的一款jQuery拖拽插件,并做适量的订制:
复制代码 代码如下:
//drag and drop
var slide = {
drag: function(e) {
var d = e.data;
var l = Math.min(Math.max(e.pageX - d.pageX + d.left, ps.limited.min), ps.limited.max);
$sliderProcess(slider, completedbar, l);
//push two parameters: 1st:percentage, 2nd: event
ps.onChanging(l / ps.limited.max, e);
},
drop: function(e) {
slider.removeClass(ps.sliderHover);
//push two parameters: 1st:percentage, 2nd: event
ps.onChanged(parseInt(slider.css('left')) / sw - ps.limited.max, e);
$().unbind('mousemove', slide.drag).unbind('mouseup', slide.drop);
}
};
if (ps.enable) {
//bind events
slider.bind('mousedown', function(e) {
var d = {
left: parseInt(slider.css('left')),
pageX: e.pageX
};
$(this).addClass(ps.sliderHover);
$().bind('mousemove', d, slide.drag).bind('mouseup', d, slide.drop);
});
}
这样当jSlider enable属性为true时,在end-user按下鼠标时绑定mousemove事件,在鼠标弹起时移除,我们只需要同步更新slider的left 属性和completedbar的width即可,同时在drag中绑定onChanging方法,在drop中绑定onChanged方法,向这两个方法推送的参数相同,1>百分比,即value值,介于0~1,2>event。
那么至此我们的jSlider插件就基本成型,向用户提供了一个可拖拽的slider。
【扩展】
有的时候用户却不是那么容易满足,于是有人高呼:“我要自己设置value,为什么不提供这个功能?”。
那么这时我们就需要为用户公开一个方法,用于设置jSlider的value,首先考虑的是作为方法需要一个作用对象(jSlider),那么此时我又不想将作用对象作为参数传入,那么我们还是将这个方法作为插件来开发,我们将方法命名为setSliderValue,开放2个参数,v(value值)和 callback(设置完成后的回调函数)。
即:$.fn.setSliderValue(v,callback);
ok,那么剩下的就是作用对象了,由之前的设计可知,在slider拖动时主要作用于2个对象,slider和completedbar,那么我们在jSlider插件末尾加上一段代码来返回slider对象:
复制代码 代码如下: