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 相关文章推荐
JavaScript方法和技巧大全
Dec 27 Javascript
JQuery中绑定事件(bind())和移除事件(unbind())
Feb 27 Javascript
jQuery结合CSS制作动态的下拉菜单
Oct 27 Javascript
jQuery ajax中使用confirm,确认是否删除的简单实例
Jun 17 Javascript
浅谈JavaScript中数组的增删改查
Jun 20 Javascript
AngularJS 中使用Swiper制作滚动图不能滑动的解决方法
Nov 15 Javascript
Vue.js 递归组件实现树形菜单(实例分享)
Dec 21 Javascript
EasyUI学习之Combobox级联下拉列表(2)
Dec 29 Javascript
vue获取input输入值的问题解决办法
Oct 17 Javascript
vue + element-ui的分页问题实现
Dec 17 Javascript
详解搭建一个vue-cli的移动端H5开发模板
Jan 17 Javascript
微信小程序仿抖音视频之整屏上下切换功能的实现代码
May 24 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
PHP数组排序之sort、asort与ksort用法实例
2014/09/08 PHP
微信支付的开发流程详解
2016/09/13 PHP
PHP+RabbitMQ实现消息队列的完整代码
2019/03/20 PHP
lib.utf.js
2007/08/21 Javascript
javascript Ext JS 状态默认存储时间
2009/02/15 Javascript
jquery插件 cluetip 关键词注释
2010/01/12 Javascript
基于jquery的划词搜索实现(备忘)
2010/09/14 Javascript
jQuery 常见操作实现方式和常用函数方法总结
2011/05/06 Javascript
JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型
2012/10/11 Javascript
jquery实现的带缩略图的焦点图片切换(自动播放/响应鼠标动作)
2013/01/23 Javascript
js仿黑客帝国字母掉落效果代码分享
2020/11/08 Javascript
Laydate时间组件在火狐浏览器下有多时间输入框时只能给第一个输入框赋值的解决方法
2016/08/18 Javascript
jQuery中的AjaxSubmit使用讲解
2016/09/25 Javascript
原生JS实现的多个彩色小球跟随鼠标移动动画效果示例
2018/02/01 Javascript
AngularJS监听ng-repeat渲染完成的方法
2018/03/20 Javascript
深入浅析JS中的严格模式
2018/06/04 Javascript
JS实现图片转换成base64的各种应用场景实例分析
2018/06/22 Javascript
解决vue动态为数据添加新属性遇到的问题
2018/09/18 Javascript
ES6中Set和Map数据结构,Map与其它数据结构互相转换操作实例详解
2019/02/28 Javascript
JS回调函数 callback的理解与使用案例分析
2019/09/09 Javascript
React-redux实现小案例(todolist)的过程
2019/09/29 Javascript
JavaScript中的惰性载入函数及优势
2020/02/18 Javascript
网站渗透常用Python小脚本查询同ip网站
2017/05/08 Python
对python3 sort sorted 函数的应用详解
2019/06/27 Python
python 中如何获取列表的索引
2019/07/02 Python
python3使用GUI统计代码量
2019/09/18 Python
Python 函数绘图及函数图像微分与积分
2019/11/20 Python
详解查看Python解释器路径的两种方式
2020/10/15 Python
python各种excel写入方式的速度对比
2020/11/10 Python
澳洲CFL商城:CHEMIST FOR LESS(中文)
2021/02/28 全球购物
澳大利亚网上书店:QBD
2021/01/09 全球购物
《唯一的听众》教学反思
2014/02/20 职场文书
授权委托书
2014/09/17 职场文书
2015年暑期实践报告范文
2015/07/13 职场文书
新员工入职感想
2015/08/07 职场文书
《月歌。》宣布制作10周年纪念剧场版《RABBITS KINGDOM THE MOVIE》
2022/04/02 日漫