jQuery插件编写步骤详解


Posted in Javascript onJune 03, 2016

本文实例讲述了jQuery插件编写步骤。分享给大家供大家参考,具体如下:

如今做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程序设计有所帮助。

Javascript 相关文章推荐
用Greasemonkey 脚本收藏网站会员信息到本地
Oct 26 Javascript
ie与ff下的event事件使用介绍
Nov 25 Javascript
纯JavaScript实现获取onclick、onchange等事件的值
Dec 29 Javascript
5个数组Array方法: indexOf、filter、forEach、map、reduce使用实例
Jan 29 Javascript
js下将金额数字每三位一逗号分隔
Feb 19 Javascript
BootStrap中Datetimepicker和uploadify插件应用实例小结
May 26 Javascript
轮播的简单实现方法
Jul 28 Javascript
JS实现将数字金额转换为大写人民币汉字的方法
Aug 02 Javascript
jQuery插件FusionCharts绘制的3D饼状图效果实例【附demo源码下载】
Mar 03 Javascript
详谈Node.js之操作文件系统
Aug 29 Javascript
JS实现元素上下左右移动效果
Oct 18 Javascript
layui点击弹框页面 表单请求的方法
Sep 21 Javascript
jQuery ajax全局函数处理session过期后的ajax跳转问题
Jun 03 #Javascript
JSON字符串转换JSONObject和JSONArray的方法
Jun 03 #Javascript
JS判断字符串变量是否含有某个字串的实现方法
Jun 03 #Javascript
JavaScript闭包实例详解
Jun 03 #Javascript
js判断某个字符出现的次数的简单实例
Jun 03 #Javascript
JS中判断字符串中出现次数最多的字符及出现的次数的简单实例
Jun 03 #Javascript
jQuery针对input的class属性写了多个值情况下的选择方法
Jun 03 #Javascript
You might like
ThinkPHP3.1的Widget新用法
2014/06/19 PHP
php判断一个数组是否为有序的方法
2015/03/27 PHP
php自定义类fsocket模拟post或get请求的方法
2015/07/31 PHP
在PHP中使用FastCGI解析漏洞及修复方案
2015/11/10 PHP
PHP有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
CI框架附属类用法分析
2018/12/26 PHP
JavaScript版代码高亮
2006/06/26 Javascript
js 分栏效果实现代码
2009/08/29 Javascript
jquery sortable的拖动方法示例详解
2014/01/16 Javascript
javascript实现动态侧边栏代码
2014/02/19 Javascript
jQuery遍历之next()、nextAll()方法使用实例
2014/11/08 Javascript
基于jQuery实现复选框是否选中进行答题提示
2015/12/10 Javascript
Jsonp 关键字详解及json和jsonp的区别,ajax和jsonp的区别
2015/12/30 Javascript
图解Javascript——作用域、作用域链、闭包
2017/03/21 Javascript
基于JavaScript表单脚本(详解)
2017/10/18 Javascript
nodejs操作mongodb的增删改查功能实例
2017/11/09 NodeJs
vue实现div拖拽互换位置
2020/07/29 Javascript
Vue 实现前进刷新后退不刷新的效果
2019/06/14 Javascript
JS如何实现封装列表右滑动删除收藏按钮
2020/07/23 Javascript
[04:04]显微镜下的DOTA2第六期——电影级别的华丽团战
2014/06/20 DOTA
[48:28]完美世界DOTA2联赛循环赛FTD vs Magma第二场 10月30日
2020/10/31 DOTA
Python-嵌套列表list的全面解析
2016/06/08 Python
python3.6使用urllib完成下载的实例
2018/12/19 Python
python爬取代理ip的示例
2020/12/18 Python
Microsoft Advertising美国:微软搜索广告
2019/05/01 全球购物
奢华时尚的创新平台:Baltini
2020/10/03 全球购物
幼儿园门卫制度
2014/01/29 职场文书
申请任职学生会干部自荐书范文
2014/02/13 职场文书
《小动物过冬》教学反思
2014/04/17 职场文书
日语专业求职信
2014/07/04 职场文书
2014年纪检工作总结
2014/11/12 职场文书
2015年三好一满意工作总结
2015/07/24 职场文书
mysql部分操作
2021/04/05 MySQL
在redisCluster中模糊获取key方式
2021/07/09 Redis
python Tkinter模块使用方法详解
2022/04/07 Python
js前端设计模式优化50%表单校验代码示例
2022/06/21 Javascript