转载自:http://blog.sina.com.cn/s/blog_6154bf970101jam7.html

如今做web开发,jquery 几乎是必不可少的,就连vs神器在2010版本开始将Jquery 及ui 内置web项目里了。至于使用jquery好处这里就不再赘述了,用过的都知道。今天我们来讨论下jquery的插件机制,jquery有着成千上万的第 三方插件,有时我们写好了一个独立的功能,也想将其与jquery结合起来,可以用jquery链式调用,这就要扩展jquery,写成插件形式了,如下 面就是一个简单扩展Jquery对象的demo:

//sample:扩展jquery对象的方法,bold()用于加粗字体。

(function ($) {

$.fn.extend({

"bold": function () {

///《summary>

/// 加粗字体

///《/summary>

return this.css({ fontWeight: "bold" });

}

});

})(jQuery);
调用方式:

这是一个非常简单的扩展。接下来我们一步步来解析上面的代码。

一、jquery的插件机制

为了方便用户创建插件,jquery提供了jQuery.extend()和jQuery.fn.extend()方法。

1. jQuery.extend() 方法有一个重载。

  jQuery.extend(object)
,一个参数的用于扩展jQuery类本身,也就是用来在jQuery类/命名空间上增加新函数,或者叫静态方法,例如jQuery内置的
ajax方法都是用jQuery.ajax()这样调用的,有点像 “类名.方法名”
静态方法的调用方式。下面我们也来写个jQuery.extend(object)的例子:

//扩展jQuery对象本身

jQuery.extend({

"minValue": function (a, b) {

///《summary>

/// 比较两个值,返回最小值

///《/summary>

return a 《 b ? a : b;

},

"maxValue": function (a, b) {

///《summary>

/// 比较两个值,返回最大值

///《/summary>

return a > b ? a : b;

}

});

//调用

var i = 100; j = 101;

var min_v = $.minValue(i, j); // min_v 等于 100

var max_v = $.maxValue(i, j); // max_v 等于 101
重载版本:jQuery.extend([deep], target, object1, [objectN])

用一个或多个其他对象来扩展一个对象,返回被扩展的对象。
  
如果不指定target,则给jQuery命名空间本身进行扩展。这有助于插件作者为jQuery增加新方法。
  
如果第一个参数设置为true,则jQuery返回一个深层次的副本,递归地复制找到的任何对象。否则的话,副本会与原对象共享结构。

未定义的属性将不会被复制,然而从对象的原型继承的属性将会被复制。
参数
  
deep:      
可选。如果设为true,则递归合并。
  
target:    
待修改对象。
  
object1:   待合并到第一个对象的对象。
  
objectN:   可选。待合并到第一个对象的对象。
示例1:
合并 settings 和 options,修改并返回 settings。
var settings = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
jQuery.extend(settings, options);
结果:
settings == { validate: true, limit: 5, name: "bar" }

示例2:
合并 defaults 和 options, 不修改 defaults。
var empty = {};
var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
var settings = jQuery.extend(empty, defaults, options);
结果:
settings == { validate: true, limit: 5, name: "bar" }
empty == { validate: true, limit: 5, name: "bar" }
这个重载的方法,我们一般用来在编写插件时用自定义插件参数去覆盖插件的默认参数。

jQuery.fn.extend(object)扩展 jQuery 元素集来提供新的方法(通常用来制作插件)。

首先我们来看fn 是什么东西呢。查看jQuery代码,就不难发现。

jQuery.fn = jQuery.prototype = {

   init: function( selector, context ) {.....};
};

原来 jQuery.fn =
jQuery.prototype,也就是jQuery对象的原型。那jQuery.fn.extend()方法就是扩展jQuery对象的原型方法。我
们知道扩展原型上的方法,就相当于为对象添加”成员方法“,类的”成员方法“要类的对象才能调用,所以使用
jQuery.fn.extend(object)扩展的方法,
jQuery类的实例可以使用这个“成员函数”。jQuery.fn.extend(object)和jQuery.extend(object)方法一
定要区分开来。

二、自执行的匿名函数/闭包

1.
什么是自执行的匿名函数?

     它是指形如这样的函数: (function {//
code})();
    2. 疑问
为什么(function {// code})();可以被执行, 而function {// code}();却会报错?
    3.
分析

(1). 首先,
要清楚两者的区别:    
(function {// code})是表达式, function {//
code}是函数声明.

(2). 其次,
js"预编译"的特点:    
js在"预编译"阶段, 会解释函数声明,
但却会忽略表式.

(3). 当js执行到function() {//code}();时, 由于function()
{//code}在"预编译"阶段已经被解释过, js会跳过function(){//code}, 试图去执行();,
故会报错;

当js执行到(function {// code})();时, 由于(function {// code})是表达式,
js会去对它求解得到返回值, 由于返回值是一 个函数, 故而遇到();时, 便会被执行.

另外,
函数转换为表达式的方法并不一定要靠分组操作符(),我们还可以用void操作符,~操作符,!操作符……

例如:
   bootstrap 框架中的插件写法:
   !function($){
  //do something;
   }(jQuery);


   (function($){
  //do something;
   })(jQuery); 是一回事。

匿名函数最大的用途是创建闭包(这是JavaScript语言的特性之一),并且还可以构建命名空间,以减少全局变量的使用。
例如:
    
var a=1;
    
(function()(){
    var a=100;
  })();
     
alert(a); //弹出 1

三、一步一步封装JQuery插件

接下来我们一起来写个高亮的jqury插件
1.定一个闭包区域,防止插件"污染"

//闭包限定命名空间

(function ($) {

})(window.jQuery);
2.jQuery.fn.extend(object)扩展jquery 方法,制作插件
//闭包限定命名空间

(function ($) {

$.fn.extend({

"highLight":function(options){

//do something

}

});

})(window.jQuery);
3.给插件默认参数,实现 插件的功能
//闭包限定命名空间

(function ($) {

$.fn.extend({

"highLight": function (options) {

var opts = $.extend({}, defaluts, options); //使用jQuery.extend
覆盖插件默认参数

this.each(function () {  //这里的this 就是 jQuery对象

//遍历所有的要高亮的dom,当调用 highLight()插件的是一个集合的时候。

var $this = $(this); //获取当前dom 的 jQuery对象,这里的this是当前循环的dom

//根据参数来设置 dom的样式

$this.css({

backgroundColor: opts.background,

color: opts.foreground

});

});

}

});

//默认参数

var
defaluts = {

foreground: 'red',

background: 'yellow'

};

})(window.jQuery);
到这一步,高亮插件基本功能已经具备了。调用代码如下:
$(function () {

$("p").highLight(); //调用自定义 高亮插件

});
这里只能 直接调用,不能链式调用。我们知道jQuey是可以链式调用的,就是可以在一个jQuery对象上调用多个方法,如:
$('#id').css({marginTop:'100px'}).addAttr("title","测试“);
但是我们上面的插件,就不能这样链式调用了。比如:$("p").highLight().css({marginTop:'100px'});
//将会报找不到css方法,原因在与我的自定义插件在完成功能后,没有将 jQuery对象给返回出来。接下来,return
jQuery对象,让我们的插件也支持链式调用。(其实很简单,就是执行完我们插件代码的时候将jQuery对像return
出来,和上面的代码没啥区别)
//闭包限定命名空间

(function ($) {

$.fn.extend({

"highLight": function (options) {

var opts = $.extend({}, defaluts, options); //使用jQuery.extend
覆盖插件默认参数

return this.each(function () {  //这里的this 就是
jQuery对象。这里return 为了支持链式调用

//遍历所有的要高亮的dom,当调用 highLight()插件的是一个集合的时候。

var $this = $(this); //获取当前dom 的 jQuery对象,这里的this是当前循环的dom

//根据参数来设置 dom的样式

$this.css({

backgroundColor: opts.background,

color: opts.foreground

});

});

}

});

//默认参数

var
defaluts = {

foreground: 'red',

background: 'yellow'

};

})(window.jQuery);
4.暴露公共方法 给别人来扩展你的插件(如果有需求的话)
比如的高亮插件有一个format方法来格式话高亮文本,则我们可将它写成公共的,暴露给插件使用者,不同的使用着根据自己的需求来重写该format方法,从而是高亮文本可以呈现不同的格式。

//公共的格式化 方法.
默认是加粗,用户可以通过覆盖该方法达到不同的格式化效果。

$.fn.highLight.format = function (str) {

return "《strong>" + str + "《/strong>";

}
5.插件私有方法
 有些时候,我们的插件需要一些私有方法,不能被外界访问。例如 我们插件里面需要有个方法
来检测用户调用插件时传入的参数是否符合规范。
6.其他的一些设置,如:为你的插件加入元数据插件的支持将使其变得更强大。

完整的高亮插件代码如下:

//闭包限定命名空间

(function ($) {

$.fn.extend({

"highLight": function (options) {

//检测用户传进来的参数是否合法

if (!isValid(options))

return this;

var opts = $.extend({}, defaluts, options); //使用jQuery.extend
覆盖插件默认参数

return this.each(function () {  //这里的this 就是
jQuery对象。这里return 为了支持链式调用

//遍历所有的要高亮的dom,当调用 highLight()插件的是一个集合的时候。

var $this = $(this); //获取当前dom 的 jQuery对象,这里的this是当前循环的dom

//根据参数来设置 dom的样式

$this.css({

backgroundColor: opts.background,

color: opts.foreground

});

//格式化高亮文本

var markup = $this.html();

markup = $.fn.highLight.format(markup);

$this.html(markup);

});

}

});

//默认参数

var
defaluts = {

foreground: 'red',

background: 'yellow'

};

//公共的格式化
方法. 默认是加粗,用户可以通过覆盖该方法达到不同的格式化效果。

$.fn.highLight.format = function (str) {

return "《strong>" + str + "《/strong>";

}

//私有方法,检测参数是否合法

function
isValid(options) {

return !options || (options && typeof options === "object")
? true : false;

}

})(window.jQuery);
调用:
       
//调用

//调用者覆盖 插件暴露的共公方法

$.fn.highLight.format = function (txt) {

return "《em>" + txt + "《/em>"

}

$(function () {

$("p").highLight({ foreground: 'orange', background: '#ccc' });
//调用自定义 高亮插件

});

如何编写JQuery 插件详解的更多相关文章

  1. Bootstrap进阶四:jQuery插件详解

    一.模态对话框(Modal) 模态框经过了优化,更加灵活,以弹出对话框的形式出现,具有最小和最实用的功能集. 不支持同时打开多个模态框 千万不要在一个模态框上重叠另一个模态框.要想同时支持多个模态框, ...

  2. jquery系列教程7-自定义jquery插件全解:对象函数、全局函数、选择器

    点击打开: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件操作全解 jquery系列教程5-动 ...

  3. Vue插件编写、用法详解(附demo)

    Vue插件编写.用法详解(附demo) 1.概述 简单来说,插件就是指对Vue的功能的增强或补充. 比如说,让你在每个单页面的组件里,都可以调用某个方法,或者共享使用某个变量,或者在某个方法之前执行一 ...

  4. jQuery:详解jQuery中的事件(二)

    上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 接上篇jQuery:详解jQuery中的事件(一) ...

  5. jQuery.validator 详解二

    前言:上一篇详细的介绍了jQuery.validator( 版本v1.13.0 )的验证规则,这一篇重点讲述它的源码结构,及如何来对元素进行验证,错误消息提示的内部实现 一.插件结构(组织方式) 在讲 ...

  6. Uploadify 上传文件插件详解

    Uploadify 上传文件插件详解 Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示.不过官方提供的实例时php版本的,本文将详细介绍Uploadify在Aspnet中 ...

  7. jQuery.validator 详解

    jQuery.validator 详解二 前言:上一篇详细的介绍了jQuery.validator( 版本v1.13.0 )的验证规则,这一篇重点讲述它的源码结构,及如何来对元素进行验证,错误消息提示 ...

  8. Maven系列第6篇:生命周期和插件详解,此篇看过之后在maven的理解上可以超越同级别90%的人!

    maven系列目标:从入门开始开始掌握一个高级开发所需要的maven技能. 这是maven系列第6篇. 整个maven系列的内容前后是有依赖的,如果之前没有接触过maven,建议从第一篇看起,本文尾部 ...

  9. ThreeJS系列1_CinematicCameraJS插件详解

    ThreeJS系列1_CinematicCameraJS插件详解 接着上篇 ThreeJS系列1_CinematicCameraJS插件介绍 看属性的来龙去脉 看方法作用 通过调整属性查看效果 总结 ...

随机推荐

  1. What is REST API

    What is REST REST is acronym for REpresentational State Transfer. It is architectural style for dist ...

  2. OO第二次作业总结

    OO~第二次作业总结 连续三周的电梯作业结束了,总的来说这三次作业做的还算平稳,既没有被刀,也没有刀中别人.那么接下来开始谈谈我对这三次作业的认识. 一.设计策略 我三次作业的设计思路基本上是相同的, ...

  3. 如何实现Activiti的分支条件的自定义配置(转)

    如何实现Activiti的分支条件的自定义配置 博客分类: Activiti Java SaaS   一.Activiti的流程分支条件的局限 Activiti的流程分支条件目前是采用脚本判断方式,并 ...

  4. Java的xml与map,与Bean互转

    xml与map互转,主要使用dom4j import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j. ...

  5. Desktop Central 的移动设备管理功能

    Desktop Central 的移动设备管理功能1.移动应用程序管理设备管理不会仅仅只是配置策略.检索资产信息和保护设备.应用程序管理与设置员工的移动设备一样重要.使用 Desktop Centre ...

  6. Xcode安装CocoaPods

    1.虽然Mac自带Ruby但是安装cocoapods需要gem,gem是一个管理Ruby库和程序的标准包,它通过RubyGem源来查找.安装.升级和卸载软件包.因为gem默认的服务器被墙,因此在安装之 ...

  7. String常用类

    一.String类String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象.java把String类声明的final类,不能有类.String类对象创建 ...

  8. MySQL系统变量 sql_mode 详解

    转载自:http://tech.it168.com/a2012/0822/1388/000001388401_all.shtml MySQL数据类型:SQL_MODE设置不容忽视 SQL_MODE可能 ...

  9. 第三次OO总结

    规格化设计的调研 随着50年代高级语言的出现,编译技术不断完善,涌现出多种流派的语言,其中就有里程碑式的Pascal语言:进入70年代,由于众多语言造成的不可移植.难于维护,Ada程序设计语言诞生了, ...

  10. python生成exe文件

    安装pyinstaller pyinstaller支持python2和python3 命令行安装:pip install pyinstaller pyinstaller --icon=duoguan. ...