简千叶 发表于 2025-5-29 20:22:12

jQuery插件开发 - 其实很简单

【前言】
jQuery已经被广泛使用,凭借其简洁的API,对DOM强大的操控性,易扩展性越来越受到web开发人员的喜爱,我在社区也发布了很多的jQuery插件,经常有人询问一些技巧,因此干脆写这么一篇文章给各位jQuery爱好者,算是抛砖引玉吧。
【基础】
a)样式
很多人会认为样式是个很复杂的东西,需要沉着冷静的心态加上非凡的审美观才能设计出赏心悦目的UI,抛开图片设计不说,其实css也就是那么些属性:position,margin,padding,width,height,left,top,float,border,background...

UI设计的漂亮与否在很大程度上依赖于设计人员对配色的把握和整体效果的协调。举个简单的例子,一个简单的页面,马虎的人:



    Test Page


    jQuery是一个框架!压缩后有30多k吧。



细心的人:



    Test Page
    


    jQuery是一个框架!压缩后有30多k吧。

专心的人:



    Test Page
    


    jQuery是一个框架!压缩后有30多k吧。


我们对比一下三者的UI效果:



一目了然,或许很多的站点失去关注正是因为这不起眼的font-family,font-size。当然这还只是个简单的例子,掌握css应该从简单做起,从基本入手,在实践中运用并不断深入。
b)脚本
我们同样需要对javascript有着深刻的理解,对dom, xhr, Regex, call-apply, prototype等都应该有一定的了解。
' + a + '" >' + a + '';
}

路人乙:

String.prototype.format = function() {
    var args = arguments;
    return this.replace(/{(\d{1})}/g, function() {
        return args];
    });
};

var a = new Array(1,2,3,4,5,6,7,8,9,0);
var m = '{0}';

for (var i = 0; i  bar
jquery-completed -> completed
jquery-jslider -> slider

前期UI呈现上我们不使用图片,尽量用线条、颜色来完成:
Css
/**//*----default skin----*/
.defaultbar
{}{
    margin-top: 10px;
    height: 5px;
    background-color: #FFFFE0;
    border: 1px solid #A9C9E2;
    position: relative;
    }
.defaultbar .jquery-completed
{}{
    height: 3px;
    background-color: #7d9edb;
    top: 1px;
    left:1px;
    position: absolute;
    }
.defaultbar .jquery-jslider
{}{
    height: 15px;
    background-color: #E6E6FA;
    border: 1px solid #A5B6C8;
    top: -6px;
    display: block;
    cursor: pointer;
    position: absolute;
    }
将bar的position属性设置成relative,以方便子节点的浮动(子节点使用position:absolute来获得内联浮动效果)。
那么我们可以看下这个css和html tree产生的UI效果:


ok,具备了所需的元素 - slider, completed, bar.
一些规范:

当我们画出了UI之后就可以正式编写jQuery插件代码了,不过在着之前我们还需要对jQuery插件开发的一些规范性有一些了解。
1. 使用闭包:

(function($) {
  // Code goes here
})(jQuery);这是来自jQuery官方的插件开发规范要求,使用这种编写方式有什么好处呢?

a) 避免全局依赖。

b) 避免第三方破坏。
c) 兼容jQuery操作符'$'和'jQuery '

我们知道这段代码在被解析时会形同如下代码:

var jq = function($) {
  // Code goes here
};
jq(jQuery);这样效果就一目了然了。

2. 扩展
jQuery提供了2个供用户扩展的‘基类’ - $.extend和$.fn.extend.

$.extend用于扩展自身方法,如$.ajax,$.getJSON等,$.fn.extend则是用于扩展jQuery类,包括方法和对jQuery对象的操作。为了保持jQuery的完整性,我比较趋向于使用$.fn.extend进行插件开发而尽量少使用$.extend.
3. 选择器
jQuery提供了功能强大,并兼容多种css版本的选择器,不过发现很多同学在使用选择器时并未注重效率的问题。

a)尽量使用Id选择器,jQuery的选择器使用的API都是基于getElementById或getElementsByTagName,因此可以知道效率最高的是Id选择器,因为jQuery会直接调用getElementById去获取dom,而通过样式选择器获取jQuery对象时往往会使用getElementsByTagName去获取然后筛选。

b)样式选择器应该尽量明确指定tagName,如果开发人员使用样式选择器来获取dom,且这些dom属于同一类型,例如获取所有className为jquery的div,那么我们应该使用的写法是$('div.jquery')而不是$('.jquery'),这样写的好处非常明显,在获取dom时jQuery会获取div然后进行筛选,而不是获取所有dom再筛选。
c)避免迭代,很多同学在使用jQuery获取指定上下文中的dom时喜欢使用迭代方式,如$('.jquery.child'),获取className为jquery的dom下的所有className为child的节点,其实这样编写代码付出的代价是非常大的,jQuery会不断的进行深层遍历来获取需要的元素,即使确实需要,我们也应该使用诸如$(selector,context),$('selector1>selector2'), $(selector1).children(selector2),$(selctor1).find(selector2)之类的方式。

开始编码

话题有点扯远,ok,在对UI有了清晰的认识后我们就可以使用js来输出html了。
我们使用jSlider来命名这个slider插件(为了避免插件冲突,插件命名时也应十分考究,这里我就俗一回)。
$.extend($.fn, {
        ///
        /// apply a slider UI
        ///
        jSlider: function(setting) {
        }
});在插件开发中比较标准的方式是将元数据独立出来并开放API,比如这里的setting参数传入值,有时候为了减少代码编写量,我习惯于直接在插件内赋值:

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:
 ---->sliderbar
   ----> completed bar
   ----> slider                  

百分比,即value值,介于0~1,2>event。
</p>那么至此我们的jSlider插件就基本成型,向用户提供了一个可拖拽的slider。

【扩展】
有的时候用户却不是那么容易满足,于是有人高呼:“我要自己设置value,为什么不提供这个功能?”。

那么这时我们就需要为用户公开一个方法,用于设置jSlider的value,首先考虑的是作为方法需要一个作用对象(jSlider),那么此时我又不想将作用对象作为参数传入,那么我们还是将这个方法作为插件来开发,我们将方法命名为setSliderValue,开放2个参数,v(value值)和callback(设置完成后的回调函数)。

即:$.fn.setSliderValue(v,callback);
ok,那么剩下的就是作用对象了,由之前的设计可知,在slider拖动时主要作用于2个对象,slider和completedbar,那么我们在jSlider插件末尾加上一段代码来返回slider对象:

slider.data = { bar: sliderbar, completed: completedbar };
return slider;这样我们在初始化jSlider的时候就可以直接用一个变量来获取jSlider对象,然后调用setSliderValue方法了,伪码:

var slider = $.fn.jSlider({});
slider.setSliderValue(v,function(){});setSliderValue代码:

try {
    //validate
    if (typeof v == 'undefined' || v  1) {
        throw new Error('\'v\' must be a Float variable between 0 and 1.');
    }

    var s = this;

    //validate 
    if (typeof s == 'undefined' ||
        typeof s.data == 'undefined' ||
            typeof s.data.bar == 'undefined') {
        throw new Error('You bound the method to an object that is not a slider!');
    }

    $sliderProcess(s, s.data.completed, v * s.data.bar.width());

    if (typeof callback != 'undefined') { callback(v); }
}
catch (e) {
    alert(e.message);
}这里同样调用了全局Function$sliderProcess在设置slider的value值时进行completedbar和slider的更新。由于此处进行了异常处理,所以如果end-user在确保setSliderValue被作用于jSlider对象的时候可以删除此异常处理代码。
【皮肤】
根据jSlider的API我们可以更加方便的为其设定皮肤,为了让jSlider更加专业,我们需要2张图片:

用来作为completedbar背景的'bar'和用来作为slider背景的'slider',ok,我们更新下样式:

BlueSkin
/**//*----blue skin----*/
.bluebar
{}{
    margin-top: 10px;
    height: 4px;
    background:#F7F7F7;
    border:solid 1px #3e3e3e;
    position: relative;
    }
.bluebar .jquery-completed
{}{
    height: 4px;
    background:url(../images/slider/blue/bar.gif) left center no-repeat;
    top: 0;
    left:0;
    position: absolute;
    }
.bluebar .jquery-jslider
{}{
    height: 17px;
    background:url(../images/slider/blue/slider.gif) center 0 no-repeat;
    top: -4px;
    display: block;
    cursor: pointer;
    position: absolute;
    }
.bluebar .jquery-jslider-hover
{}{
    background-position:center -17px;
    }由于在设置样式时我仍然让子节点样式使用了API的默认值,因此在创建jSlider时我们只需要设置barCssName就行了:


var blue = $.fn.jSlider({
    renderTo: '#slidercontainer',
    size: { barWidth: 500, sliderWidth: 10 },
    barCssName: 'bluebar',
    onChanging: function(percentage, e) {
        // code goes here
    }
});呈现出来的UI:

我们这样来设置其值:

//set percentage with a callback function
blue.setSliderValue(0.65, function(percentage) {
    // code goes here
});
【通用性】
当然,我们不仅可以将jSlider作为slider使用,有时候它也是一个progressbar:


(代码我就不贴了,直接在demo里查看 ;-) )
【小结】
通篇到这里就结束了,简单的介绍了一款jQuery插件的开发流程,以及开发中应该注意的细节,那么在下一篇的文章中我会向大家介绍如何打造一个通用型的 自动完成 插件。

live demo
source

 *   * Licensed  * Under an Attribution, Share Alike License * * Copyright 2008-2014 Tjatse [ thisnamemeansnothinggmail.com ]  * **/
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: jQuery插件开发 - 其实很简单