第四十三课:jQuery插件化

我们先来看一个最简单的例子:

(function($){

  $.fn.extend({     //把此插件添加到jQuery的原型上

    pluginName:function(){   //插件的名字

      return this.each(function(){     //遍历匹配元素的集合

        //插件要实现的功能

      });

    }

  });

})(jQuery);   //传入jQuery对象

由于jQuery是集化操作($("div")会选择多个div元素进行操作),而我们的插件编写应该一个元素对应一个配置对象,我们可以使用$.extend({},defaults,options)来为每个元素分配独立的配置对象。其中,defaults为默认配置对象,以防我们什么都没传时,插件也能正常运作。如果传入的配置对象options比较复杂,也就是说options的属性也是一个对象,那么我们可以使用深拷贝,$.extend(true,{},defaults,options)。

当然,你可以在上面例子中的each中做一个元素对应一个配置对象的操作,但是如果操作很多,那么在each中就会有很多代码,维护不方便。

因此,我们需要使用面向对象的写法。请看例子:

(function($){

  var Plugin = function(element, options){

  };

  Plugin.defaults = {    //默认配置

  };

  Plugin.prototype = {};

  $.fn.extend({     //把此插件添加到jQuery的原型上

    pluginName:function(options){   //插件的名字

      return this.each(function(){     //遍历匹配元素的集合

        var ui = $._data(this, "pluginname");    //看此元素在jQuey缓存系统中是否存有pluginname属性,它的值是一个Plugin实例对象

        if(!ui){

          var opts = $.extend(true,{}, Plugin.defaults , options);    //这里的默认配置对象一般写在Plugin实例构造中使用

          ui = new Plugin(this,opts);

          $._data(this,"pluginname", ui);    //一个元素对应一个Plugin实例对象,插件的功能,全部在Plugin对象中,因此,我们只需要改写Plugin构造函数以及它的原型,就能实现此插件的功能。

        }       

      });

    }

  });

})(jQuery);   //传入jQuery对象

Bootstrap在上面的基础上,进行了三大改造,第一:插件的无冲突处理。第二:将内部的对象构造器(类)放到了$.fn.pluginName.Constructor上,方便我们来扩展这个内部类。第三:利用事件代理自动初始化实例,目的是让用户只需要引入此插件,并按照规定写HTML,就能让此HTML实现插件的功能。举个例子:

(function($){

//------------------------------------------------------------------------内部的对象构造器(内部类)

  var Dropdown= function(element, options){

    $(element).on("click",this.toggle);    //当$("div").dropdowm({....})时,就会给div绑定一个click事件,如果点击了div,就会触发toggle方法。

  };

  Dropdown.defaults = {    //默认配置

  };

  Dropdown.prototype = {

    constructor:Dropdown,

    toggle:function(){

      ......

    }

  };

//--------------------------------------------------------------

  var old = $.fn.dropdown;    //因为需要重写此方法名,因此先把原始的保存在old变量中,当调用$.fn.dropdown.noConflict(),就会把它还原。

  $.fn.extend({     //把此插件添加到jQuery的原型上

    dropdown :function(options){   //插件的名字

      var args = [].slice.call(arguments,1);

      return this.each(function(){     //遍历匹配元素的集合

        var ui = $._data(this, "dropdown");    //看此元素在jQuey缓存系统中是否存有dropdown属性,它的值是一个Dropdown实例对象

        if(!ui){

          var opts = $.extend(true,{}, Dropdown.defaults , options);   //这里的默认配置对象,一般在Dropdown实例对象构造中使用。

          ui = new Dropdown(this,opts);

          $._data(this,"dropdown", ui);    //一个元素对应一个Dropdown实例对象,插件的功能,全部在Dropdown对象中,因此,我们只需要改写Dropdown构造函数以及它的原型,就能实现此插件的功能。

        }    

        if (typeof options == ‘string‘ && typeof ui[options] == ‘function‘) {  //这里添加的这段代码,是针对jQuery插件的,当我们实例化此插件后,比如:$("div").dropdown({....})后,如果想调用此插件的方法,那么,可以用$("div").dropdown(方法名, arg1,arg2....)
          ui[options].apply(ui, args);
        }    

      });

    }

  });

  $.fn.dropdown.Constructor = Dropdown;   //把内部类暴露出来,我们可以通过$.fn.dropdown.Constructor来访问,并且扩展它

  $.fn.dropdown.noConflict = function(){

    $.fn.dropdown = old;

    return this;

  }

  $(document).on("click", ".dropdown",Dropdown.prototype.toggle);    //加载完此插件后,在HTML的元素中只要有class = dropdowm,那么点击此元素,就会执行toggle方法。 

})(jQuery);   //传入jQuery对象

如果想做jQuery插件,此思想一定要掌握,面试会问,一次看不懂,多看几次就懂了,或者去看下公司里面其他人写的插件,就很容易懂了。如果大家没有很好的例子,那可以看一下我写的那个日历插件:http://www.cnblogs.com/chaojidan/p/4140725.html。在这个插件中,我是直接使用了全局变量来定义了CCalendar,这样会污染我们的全局环境,因此,我们只需要在整个代码的外面,添加一个立即执行的匿名函数,同时包装到jQuery中就行了。

(function($){

//------------------------------------------------------------------------内部的对象构造器(内部类)

  // 日历插件代码

//-------------------------------------------------------------- 

  $.fn.ccalendar = function (options) {
    return this.each(function () {
      var $this = $(this),
      data = $this.data(‘CCalendar‘),      //这个就相当于$._data(this, "CCalendar")
      if (!data) {

        data = new CCalendar(this, options);
        $this.data(‘CCalendar‘, data );  //这个就相当于$._data(this,"CCalendar“, data);
      }
    });
  };
  $.fn.ccalendar.Constructor = CCalendar;

})(jQuery)

这样一包装之后,插件代码中的方法和变量,都变成局部的了,就不会污染全局环境了,但是在使用这个日历插件时,你就需要这样调用了:

$("input").ccalendar({   .....   });

如果大家使用的是sea.js这种模块化开发的模式:

那么只需要:

define(function(require, exports, module){

  var $ = require("./jQuery.js");

  //然后再把上面的立即执行函数中的代码放到这里。

  module.exports=CCalendar;

})

这时,你既可以用jQuery的调用方式:$("input").ccalendar({   .....   });

也可以使用sea.js的调用方式:var callendar = require("./ccalendar.js");   var date = new callendar(element, { ..... })

加油!

时间: 2024-11-07 15:37:18

第四十三课:jQuery插件化的相关文章

NeHe OpenGL教程 第四十三课:FreeType库

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第四十三课:FreeType库 在OpenGL中使用FreeType库 使用FreeType库可以创建非常好看的反走样的字体,记住暴雪公司就是使用这个库的,就是那个做魔兽世界的.尝试一下吧,我只告诉你了基本的使用方式,你可以走的更远

UEditor的jQuery插件化

UEditor本身并不依赖jQuery,但如果在项目中同时使用两者的话,可能会希望使用jQuery语法创建和获取编辑器实例.为此,需要为jQuery编写插件,代码如下: (function ($) { // 注册jQuery插件 $.fn.ueditor = function () { // 如果通过jQuery获取了多个元素,可以创建多个编辑器 for (var i = 0; i < this.length; i++) { // UEditor会自己管理各个编辑器实例,不会重复创建 UE.ge

第四十三课

webapp  server与java技术基础 java技术基础及tomcat入门 tomcat配置详解 tomcat配置及案例

JAVA学习第四十三课 — 集合框架工具类(一)

一.Collections:集合框架的工具类 其中的方法都是静态的 排序方法演示 import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; class ComparaByLeng implements Comparator<String>{ public int compare(String o1, String o2) { int

AGG第四十三课 例子image1从椭圆到矩形替换问题

I am basing my code on the images1 example and I have changed the image 'partner' shape from an ellipse to a rectangle. The partner rectangle comes out at X,Y and scales and rotates, but the top left-hand corner of the image is always stuck at (x,y)=

python第四十三课——封装性

1.面向对象的三大特性:封装性.继承性.多态性 封装: 封装使用的领悟: 1).生活层面:食品.快递.计算机.明星... 2).计算机层面: ①.模块.类.函数... ②.属性数据的封装与隐藏 权限修饰符的概念: public(公共的,范围最大) protected(收保护的)default(默认,缺省) private(私有的,范围最小) python语言没有以上这些关键字: 对于python的属性私有化使用:__来实现 在设计完类,外界创建对象通过.的形式访问(设置)属性, 可能会出现跟现实

jQuery插件实例四:手风琴效果[无动画版]

手风琴效果就是内容的折叠与打开,在这个插件中,使用了三种数据来源:1.直接写在DOM结构中:2.将数据写在配置项中:3.从Ajax()中获取数据.在这一版中,各项的切换没有添加动画效果,在下一版中会是有动画效果的. 在这个插件中,CSS和JS的配置非常重要,需要特别注意.另外,加个思考,请先看完后再想这个问题:当点击其中某项时,给width直接添加animate是否合适,当快速在其上移动时,如何保证效果? 效果图预览 插件JS accordionB.js 1 ; 2 (function ($,

jquery学习(四)-如何书写自定义的jquery插件

来自锋利的jquery第二版 下面我们开始介绍如何通过现有的方法和函数,封装出既符合自己需求,有高效的插件. Jquery插件公分为3类,分别为:封装对象方法的插件.封装全局函数的插件.自定义选择器插件,在介绍插件的三种类型之前,我们先来了解书写插件的基本要点(这里转自aspwzmuma和锋利的jquery): a.插件的文件命名推荐遵循jQuery.[插件名].js的规则,以便于与其他的js文件的区分,如新插件文件jquery.newplugin.js. b.对象级别插件,所有的方法都应依附于

jQuery插件开发,jquery插件

关于jQuery插件的开发自己也做了少许研究,自己也写过多个插件,在自己的团队了也分享过一次关于插件的课.开始的时候整觉的很复杂的代码,现在再次看的时候就清晰了许多.这里我把我自己总结出来的东西分享出来,帮助那些和我一样曾经遇到过同样问题的人. 我要做什么 我想要得到的javascript 插件应该会有以下几个特征 * 以下的代码均假设存在 jQuery 插件的第一形态 面对这种情况,通常我们会通过定义function的方式来实现. function pluginName($selector){