`

jquery插件开发

    博客分类:
  • ajax
阅读更多

转自: http://www.cnblogs.com/fromearth/archive/2009/07/08/1519054.html

【前言】
jQuery已经被广泛使用,凭借其简洁的API,对DOM强大的操控性,易扩展性越来越受到web开发人员的喜爱,我在社区也发布了很多的jQuery插件,经常有人询问一些技巧,因此干脆写这么一篇文章给各位jQuery爱好者,算是抛砖引玉吧。

【基础】
a) 样式
很 多人会认为样式是个很复杂的东西,需要沉着冷静的心态加上非凡的审美观才能设计出赏心悦目的UI,抛开图片设计不说,其实css也就是那么些属 性:position,margin,padding,width,height,left,top,float,border,background...

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

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Test Page</title>
</head>
<body>
    jQuery是一个框架!压缩后有30多k吧。
</body>
</html>

 细心的人:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Test Page</title>
    <style type="text/css">
        body
        {
            font-family:'宋体';
            font-size:12px;
            }
    </style>
</head>
<body>
    jQuery是一个框架!压缩后有30多k吧。
</body>
</html>

 专心的人:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Test Page</title>
    <style type="text/css">
        body
        {
            font-family:'Verdana','宋体';
            font-size:12px;
            }
    </style>
</head>
<body>
    jQuery是一个框架!压缩后有30多k吧。
</body>
</html>

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



一目了然,或许很多的站点失去关注正是因为这不起眼的font-family,font-size。当然这还只是个简单的例子,掌握css应该从简单做起,从基本入手,在实践中运用并不断深入。

b)脚本
我们同样需要对javascript有着深刻的理解,对dom, xhr, Regex, call-apply, prototype等都应该有一定的了解。

有人会说要这些有啥用啊,对dom的操作其实通过getElementById, getElementsByTagName以及其他的API都可以轻松的完成,这话是没错,当思路确定后,思想才是重点,一段代码是精华还是糟粕很容易就 可以区分出来,究其原因还是取决你自己,举个简单的例子,大量的html组装,

路人甲:

var a = new Array(10);
var menu = '';   
for (var i = 0; i < a.length; i++) {
  menu += '<li class="style_' + a[i] + '" >' + a[i] + '</li>';
}

 路人乙:

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

var a = new Array(1,2,3,4,5,6,7,8,9,0);
var m = '<li class="style_{0}" >{0}</li>';

for (var i = 0; i < a.length; i++) {
    menu += m.format(a[i]);
}

 在实现方式明确的情况下,优雅高效的代码显然更具吸引力。

【实践
jQuery开发或使用,更多的灵感是来自实践,而不是copy||paste(奉行拿来主义的同学可以离开了)。

那么在这里我会用一个简单的例子来阐述jQuery插件开发的流程,能否举一反三就看各位看官了。

【目的】

开发一个插件之前我们需要对自己的目的有一个清醒的认识,有很明确的方向感,那么此次我作为示例插件的目的,就是呈现一个用于UI的Slider - 滑动条 ,常年从事于或暂时专注于win32开发的同学应该比较了解。

草图

真正动手编码之前我们还需要有一个草图来描述自己插件的“长相”(事件驱动或API封装的可以忽略)。
很多的同学在做UI开发前往往会忙于搜集各种小图片(非精通ps或iconworkshop人士),其实漂亮的图标的确可以美化我们的UI,不过我一般的处理方式是编写易于扩展的css,前期的UI呈现尽量少使用图片,多用线条完成。

ok,言归正卷,那么我的slider设计草图是:

 

解释下下文将用到的几个词:
slider: 此部分是作为拖拽手柄来使用,用户可以通过拖拽此部分来更新completed bar的位置。
completed: 此部分作为bar的内嵌元素,作为特殊效果来显示slider与起始点的距离,亦即与slider的value值关联。
bar: slider的载体,completed的满值。

思路:
slider作为手柄提供拖拽功能,作用区域为bar,拖拽过程中completed条必须实时更新(长度),影响区域为slider至bar左端的距离。

【编码】

开发jQuery UI/Effect 插件在很多时候都需要与UI交互,因此在呈现上需要提供Html tree来绘制我们的插件,最终通过js dom来输出,那么在绘制简单的dom结构的时候我会直接用js来完成,不过如果嵌套比较复杂的话,我们还是应该先用html来完成,然后转变成js输 出。

<div class="defaultbar">
  <div class="jquery-completed"> </div>
  <div class="jquery-jslider"> </div>
</div>
 

deafultbar -> bar
jquery-completed -> completed
jquery-jslider -> slider

前期UI呈现上我们不使用图片,尽量用线条、颜色来完成:

/*----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, {
        ///<summary>
        /// apply a slider UI
        ///</summary>
        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:
<div> ---->sliderbar
<div>&nbsp;</div>   ----> completed bar
<div>&nbsp;</div>   ----> slider                  
</div>
<-----------*/
var sliderbar = $('<div><div>&nbsp;</div><div>&nbsp;</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')) / 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对象:

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 < 0 || 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[width]和slider[left]的更新。由于此 处进行了异常处理,所以如果end-user在确保setSliderValue被作用于jSlider对象的时候可以删除此异常处理代 码。

皮肤
根据jSlider的API我们可以更加方便的为其设定皮肤,为了让jSlider更加专业,我们需要2张图片:

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

/*----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[google code]

分享到:
评论

相关推荐

    jQuery插件开发全解析

    ### jQuery插件开发全解析 #### 一、引言 jQuery作为一款优秀的JavaScript库,在前端开发领域具有举足轻重的地位。它简化了许多常见的JavaScript任务,使得开发者能够更轻松地处理DOM操作、事件处理以及Ajax交互等...

    jquery 插件开发

    jquery插件开发是提高前端开发效率的重要方式之一。在本篇文章中,我们将详细解析如何通过$.extend()方法扩展jQuery、如何通过$.fn向jQuery添加新的方法以及如何使用$.widget()方法应用jQuery UI的部件工厂方式创建...

    jQuery插件开发学习

    这篇“jQuery插件开发学习”的主题旨在帮助开发者深入理解如何利用jQuery来开发自定义插件,提高代码复用性和项目效率。下面我们将详细探讨jQuery插件开发的相关知识点。 首先,了解jQuery的核心概念是至关重要的。...

    jQuery插件开发的五种形态小结

    总结来说,jQuery插件开发中的五种形态小结通过一系列的示例和说明,为开发者展示了如何创建一个高效、可维护的插件。这五个形态涉及到了代码的独立性、链式操作、插件的可配置性、生命周期的管理、无冲突处理以及...

    JQuery插件开发

    **jQuery插件开发** 在Web开发领域,jQuery是一款广泛使用的JavaScript库,它简化了DOM操作、事件处理、动画效果和Ajax交互。jQuery插件是扩展jQuery功能的一种方式,允许开发者根据需求定制各种功能,如表单验证、...

    jquery 插件开发 pdf

    jQuery插件开发是扩展这个库功能的一种常见方式,使得开发者能够根据项目需求创建自定义功能。以下是对jQuery插件开发的详细讲解: 1. **插件基础** - jQuery插件通常是通过扩展jQuery对象的原型链来实现的,这...

    jQuery插件开发详解

    《jQuery插件开发详解》 在Web开发领域,jQuery是一个广泛应用的JavaScript库,它极大地简化了DOM操作、事件处理和动画制作。对于开发者而言,掌握jQuery插件的开发技巧是提升工作效率的重要一环。本篇将深入探讨...

    jQuery插件开发及常用插件大全.zip

    jQuery插件开发及常用插件大全PDF;jQuery插件开发.pdf、jQuery常用插件大全.pdf

    jquery插件开发文档

    jQuery插件开发是一项重要的技能,可以让开发者通过创建可复用的代码片段来增强jQuery库的功能。根据提供的文档内容,以下是一些关于jQuery插件开发的关键知识点: 1. 基本插件结构 在编写jQuery插件时,首先要了解...

    跟我一起学JQuery插件开发

    首先,要学习jQuery插件开发,我们先要理解插件的概念。jQuery插件本质上是通过某种机制对jQuery核心模块进行扩展的方法或额外功能。在编写属于自己的插件时,我们不仅可以提高开发效率,还可以在不同的项目中重复...

    jQuery插件开发详细教程

    jQuery插件开发是一项能够极大提升前端开发效率和代码可复用性的技术。在学习开发jQuery插件之前,需要先了解一些基础概念和最佳实践,以及避免在开发过程中的一些常见陷阱。 首先,我们需要掌握什么是jQuery插件。...

    老司机带你解读jQuery插件开发流程

    在学习jQuery插件开发之前,需要了解jQuery库本身的功能和组成。jQuery是一个快速、小巧且功能丰富的JavaScript库,它简化了HTML文档遍历、事件处理、动画和Ajax交互等操作。在进行jQuery插件开发时,尤其需要关注...

    通用 JQuery 插件 开发

    **通用JQuery插件开发详解** 在Web开发领域,jQuery是一个广泛使用的JavaScript库,它极大地简化了DOM操作、事件处理、动画制作以及Ajax交互。由于其简洁的API和丰富的功能,jQuery成为创建交互式网页的强大工具。...

    JQuery插件的写法 最常用的jquery插件开发方式(教程合集).zip

    JQuery插件的写法 最常用的jquery插件开发方式(教程合集) jquery插件的例子 jQuery插件开发教程_看这一本就行了 JQuery插件写法 jq插件最常用的写法

    详解jQuery插件开发方式

    jQuery插件开发是创建可复用、模块化代码的一种有效方式,它允许开发者扩展jQuery的功能,满足特定需求。本文将深入探讨jQuery插件开发的几个关键点:jQuery扩展、私有域以及定义插件的基本步骤。 首先,我们来看...

    jQuery插件开发精品教程让你的jQuery提升一个台阶

    ### jQuery插件开发精品教程 #### 一、引言 jQuery是一个广泛使用的JavaScript库,其核心功能之一是通过插件扩展其功能。在这一部分,我们将了解到插件对jQuery的重要性,以及如何使用插件来提升jQuery的能力。 ##...

    jQuery插件开发精品教程(让你的jQuery更上一个台阶)

    学习jQuery插件开发对于任何希望提升自身前端开发能力的开发者而言,是一项非常重要的技能。 在插件开发中,首先需要了解的是插件开发的基本模式。根据《jQuery高级编程》所述,jQuery插件开发主要有以下几种方式:...

    JQuery插件开发 + 插件

    这篇博文“JQuery插件开发 + 插件”可能涉及到如何创建自定义的jQuery插件以及如何利用这些插件来增强网页功能。下面我们将深入探讨jQuery插件开发的相关知识点。 一、jQuery插件基础 1. 插件定义:jQuery插件是...

Global site tag (gtag.js) - Google Analytics