第四十三课: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, { ..... })
加油!
第四十三课:jQuery插件化的更多相关文章
- NeHe OpenGL教程 第四十三课:FreeType库
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- UEditor的jQuery插件化
UEditor本身并不依赖jQuery,但如果在项目中同时使用两者的话,可能会希望使用jQuery语法创建和获取编辑器实例.为此,需要为jQuery编写插件,代码如下: (function ($) { ...
- wangEditor的jQuery插件化
wangEditor是一款优秀的Web富文本编辑器.这篇随笔中讲述的wangEditor版本是2.1.22,由于它依赖于jQuery(作者打算在第三版中取消对jQuery的依赖),那么如果能使用$(& ...
- UEditor的jQuery插件化 -转
UEditor本身并不依赖jQuery,但如果在项目中同时使用两者的话,可能会希望使用jQuery语法创建和获取编辑器实例.为此,需要为jQuery编写插件,代码如下: (function ($) { ...
- 潭州课堂25班:Ph201805201 django 项目 第四十三课 后台 用户管理前后功能实现 (课堂笔记)
用户的展示,编辑,删除, 把用户显示出来,用户名,员工(是,否), 超级用户(是, 否) 活跃状态,(非活跃示为删除) 在前台要显示该用户所属的用户组,在前台代码中是调用类的属性,所以在 user 的 ...
- python第四十三课——封装性
1.面向对象的三大特性:封装性.继承性.多态性 封装: 封装使用的领悟: 1).生活层面:食品.快递.计算机.明星... 2).计算机层面: ①.模块.类.函数... ②.属性数据的封装与隐藏 权限修 ...
- Android 插件化开发(四):插件化实现方案
在经过上面铺垫后,我们可以尝试整体实现一下插件化了.这里我们先介绍一下最简单的实现插件化的方案. 一.最简单的插件化实现方案 最简单的插件化实现方案,对四大组件都是适用的,技术面涉及如下: 1). 合 ...
- Gradle 1.12用户指南翻译——第四十三章. 构建公告插件
本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- 【技术分享会】 @第四期 JQuery插件
本讲内容 JavaScript JQuery JQuery插件 实例 JavaScript 前端开发工程师必须掌握的三种技能 描述内容的HTML 描述网页样式的CSS 描述网页行为的JavaScrip ...
随机推荐
- struts2 redirect 配置动态传递参数
<action name="actionName" class="com.towerking.TestAction" method="execu ...
- linux 打包压缩工具
以.gz结尾 gzip 压缩工具压缩的文件gzip+文件名[root@test ~]# gzip 2.txt[root@test ~]# ls2.txt.gz testgzip -d +压缩包[roo ...
- ffmpeg编译x264, 这个libffmpeg即可解码又可以h264编码
http://blog.csdn.net/u012917616/article/details/40921861 不废话,直接上.sh脚本: export NDK=/home/xxx/my_sof ...
- ZBrush中的SubTool工具该怎样使用
今天的ZBrush教程中将为大家引入一个新的工具SubTool,使用SubTool您可以添加PolyMesh至当前编辑的模型中,它的出现改变了过去ZBrush不能同时编辑多个模型的弊端. 查看详细的视 ...
- HDU 5017 Ellipsoid 模拟退火第一题
为了补这题,特意学了下模拟退火算法,感觉算法本身不是很难,就是可能降温系数,步长等参数不好设置. 具体学习可以参见: http://www.cnblogs.com/heaad/archive/2010 ...
- string 类的实现
. #include<iostream> . #include<iomanip> . using namespace std; . . class String{ . frie ...
- yepnope初体验
真是一个百花齐放的项目,在熟悉代码的过程中,看到各种前端.后端技术,这回又冒出一个yepnope的东东,搜索了一下,不是什么新技术,打开官方网站,已经弃用的通知非常醒目,但仍提供相关文档在github ...
- 浅析CSS——元素重叠及position定位的z-index顺序
多次在项目中遇到html页面元素的非期待重叠错误,多数还是position定位情况下z-index的问题.其实每次解决类似问题思路大致都是一样的,说到底还是对z-index的理解比较模糊,可以解决问题 ...
- [资料]Nginx做IP访问限制以及正则规则
nginx配置location总结及rewrite规则写法 Nginx Location配置总结 Nginx 禁止某个IP访问 server { listen 443; root /webroot/; ...
- text/html与text/plain有什么区别?
MIME是服务器通知客户机传送文件是什么类型的主要方法,客户机浏览器也通过MIME告诉服务器它的参数. 在网上,如果接收到的文件没有MIME头,就默认它为HTML格式.但这样也不好,因为当MIME的包 ...