举例说明jquery插件的编写方法
jquery插件开发分为类级别开发和对象级别开发
类级别($.extend)
jQuery.extend(object)
类级别就是用来在jQuery类/命名空间上增加新函数,可以理解为拓展jquery类,最明显的例子是$.ajax(...)
,ajax方法都是用jQuery.ajax()
这样调用的,有点像 “类名.方法名” 静态方法的调用方式。开发扩展其方法时使用$.extend
方法,即jQuery.extend(object);
jQuery.extend() 方法有一个重载
下面我们也来写个jQuery.extend(object)的例子:
jQuery.extend({"minValue": function (a, b) {return a < b ? a : b;},"maxValue": function (a, b) {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" }
这个重载的方法,我们一般用来在编写插件时用自定义插件参数去覆盖插件的默认参数
对象级别
对象级别则可以理解为基于对象的拓展,如$("#table").changeColor(...);
这里这个changeColor呢,就是基于对象的拓展了。
开发扩展其方法时使用$.fn.extend
方法,即jQuery.fn.extend(object);
jQuery.fn.extend(object)
扩展jQuery元素集来提供新的方法(通常用来制作插件)
首先准备好一个架子
;(function($){})(jQuery);
这个架子是你编写插件代码要写入的空间,下面简单解释一下这个架子
1.自执行的匿名函数:是指形如这样的函数:
(function {// code})();
在jQuery环境下封装自己的插件,首先为避免与其他库的冲突,需要在插件的后面传一个jQuery参数进去,对应的函数里面的参数写入$
2 为避免出现问题,需在插件的前后加入分号(分号的增加并不会影响程序的运行)
3.为什么(function{// code})();
可以被执行, 而function{// code}();
却会报错?
首先, 要清楚两者的区别: (function {// code})
是表达式, function {// code}
是函数声明.
其次, js"预编译"的特点: js在"预编译"阶段, 会解释函数声明, 但却会忽略表式.
当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
再上一个架子
;(function($){$.fn.tab = function(options){var defaults = {//各种参数,各种属性}var options = $.extend(defaults,options);this.each(function(){ //没有必要再作 $(this) ,因为"this"已经是 jQuery 对象了.$(this) 与 $($('.tab')) 是相同的//各种功能});return this; //直接写成return this.each()这里可以省略}
})(jQuery);
这个架子就是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)方法一 定要区分开来
$.fn.tab tab是这个功能插件的名字,可任意改变名字
var options = $.extend(defaults,options); 这个是利用extend方法把 defaults对象的方法属性全部整合到 options里,也就是options继承了defaults对象的方法以及属性。这个defaults和options名字是可以随意更改的,只要是满足js的命名规范
this.each(function(){});是实现功能代码的地方
tab选项卡实例
1.先备好html
<div class="tab"><ul class="tab_nav"><li class="current">html</li><li>css</li><li>js</li></ul><div class="tab_content"><div style="display:block;">html</div><div>css</div><div>js</div></div>
</div>
2.现在来写插件代码
;(function($){$.fn.tab = function(options){ var defaults = {//各种参数,各种属性}var options = $.extend(defaults,options);this.each(function(){ //各种功能 //可以理解成功能代码var _this = $(this);_this.find('.tab_nav>li').click(function(){$(this).addClass('current').siblings().removeClass('current');var index = $(this).index();_this.find('.tab_content>div').eq(index).show().siblings().hide();});});return this;}
})(jQuery);
3.在html代码里我们只需要:
<script>$(function(){$('.tab').tab();});
</script>
1) 找到外部容器,并调用你所写的tab方法(就是你所写的插件名字):
$.fn.tab = function(options){}
2) 作为可扩展性的插件代码里面的class元素以及事件是不可以写死的;解决这个问题就要在var defaults = {}
中配置它
$.fn.tab = function(options){var defaults = {currentClass:'current',tabNav:'.tab_nav>li',tabContent:'.tab_content>div'}var options = $.fn.extend(defaults,options);this.each(function(){var _this = $(this);_this.find(options.tabNav).click(function(){$(this).addClass(options.currentClass).siblings().removeClass(options.currentClass);var index = $(this).index();_this.find(options.tabContent).eq(index).show().siblings().hide();});});return this;
}
因为extends将default对象的属性以及方法都整合到了options里,这时候只需要用options调用就可以了
4.同样的如果需求是把click事件改为mouseover事件,此时我们需要用到on() or bind() ,这样就方便我们改事件参数啦,如下:
$.fn.tab = function(options){var defaults = {currentClass:'current',tabNav:'.tab_nav>li',tabContent:'.tab_content>div',eventType:'click'}var options = $.fn.extend(defaults,options);this.each(function(){var _this = $(this);_this.find(options.tabNav).on(options.eventType,function(){$(this).addClass(options.currentClass).siblings().removeClass(options.currentClass);var index = $(this).index();_this.find(options.tabContent).eq(index).show().siblings().hide();});});return this;
}
因为需求是mouseover,这里就不需要改插件源码啦,直接在html里的js代码进行相应的变化就ok啦
<script>$(function(){$('.tab').tab({currentClass:'current123',eventType:'mouseover'.....});});
</script>
5:jQuery最强大的特性之一莫过于链式操作,此时如果你在$('.tab').tab()后面追加操作,你会发现无法实现,如下:
$('.tab').tab().find('.tab_nav>li').css('background','red');
但是当你return this把对象返回出去的时候你会发现又重新实现了
总结
jQuery 插件使库把最有用的功能抽象成可重用代码,这将进一步提高开发效率。下面是你开发jQuery 插件时的注意事项:
总是把插件包装在闭包中 { / plugin goes here / })( jQuery );
不在插件函数的立即作用域中额外包装 this 关键字
总是让插件函数返回 this 关键字以保持 chainability ,除非插件有真正的返回值
不要传给插件大量参数,应该传一个可以覆盖插件默认选项的设置对象
在单个插件中,不要让一个以上的名称空间搞乱了 jQuery.fn 对象;总是为方法、事件和数据定义名称空间
据说90%以上的插件就是用$.fn.extend()方式实现的,因为jquery的特色就是先选择dom节点,然后链式处理这些节点。还有不常见的$.extend()插件编写方式,该方式编写的插件是在jquery命名空间内添加方法,也就是说在使用时不需要先选择dom节点,使用时直接$.method()即可
接下来我们一起来写个高亮的jqury插件
定一个闭包区域,防止插件"污染"
(function ($) {})(window.jQuery); //window.jQuery = window.$ = jQuery;
jQuery.fn.extend(object)扩展jquery 方法,制作插件
(function ($) { //闭包限定命名空间$.fn.extend({"highLight":function(options){//do something}});
})(window.jQuery);
给插件默认参数,实现 插件的功能
//闭包限定命名空间
(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 $this.css({ //根据参数来设置 dom的样式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 $this.css({ //根据参数来设置 dom的样式backgroundColor: opts.background,color: opts.foreground});});}}); var defaluts = { //默认参数foreground: 'red',background: 'yellow'};
})(window.jQuery);
暴露公共方法给别人来扩展你的插件(如果有需求的话)
比如的高亮插件有一个format方法来格式话高亮文本,则我们可将它写成公共的,暴露给插件使用者,不同的使用者根据自己的需求来重写该format方法,从而是高亮文本可以呈现不同的格式
//公共的格式化方法. 默认是加粗,用户可以通过覆盖该方法达到不同的格式化效果
$.fn.highLight.format = function (str) { return "<strong>" + str + "</strong>";
}
插件私有方法
有些时候,我们的插件需要一些私有方法,不能被外界访问。例如 我们插件里面需要有个方法 来检测用户调用插件时传入的参数是否符合规范
其他的一些设置,如:为你的插件加入元数据插件的支持将使其变得更强大。
完整的高亮插件代码如下:
//闭包限定命名空间
(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插件的编写方法相关推荐
- Jquery插件的编写和使用
第七章 Jquery插件的编写和使用 插件的定义: 插件也称为扩展,是一种遵循一定规范的应用程序接口编写出来的程序. 下面是Jquery插件的编写很使用:要查看请点击:Jquery插件的编写很 ...
- Android 中插件的编写方法
java中插件主要使用反射机制来完成,Android与Java中一样也是通过反射机制,不同的是Android中使用的是DexClassLoader和PathClassLoader. 原因很简单,And ...
- jq插件的编写方法(自定义jq插件)
jq插件用起来很方便,给客户端的编程带来很大的好处,节省大量的开发时间 我用Jq也有好长时间了,今天在一个项目中用一个插件的时候,忽然感觉这个插件有一个bug 这让我心生了自己写一个jq插件的想法 下 ...
- jQuery插件编写,
jQuery插件编写 jQuery插件 最近搞jquery插件的编写这里做下笔记 给jquery扩展的方式很多,看的我眼花缭乱 方式1 $.fun=function(){} 方式2 $.fn.fun= ...
- 锋利的jQuery--编写jQuery插件(读书笔记五)[完结篇]
1.表单验证插件Validation 2.表单插件Form 3.动态事件绑定插件livequery 可以为后来的元素绑定事件 类似于jQuery中的live()方法 4.jQuer ...
- jquery插件分类与编写详细讲解
1. 插件种类 插件其实就是对现有的方法(或者叫函数)做一个封装,方便重用提高开发效率. jQeury主要有2种类型 1)实例对象方法插件 开发能让所有的jquery实例对象都可以调用的方法. ...
- 如何编写一个Jquery插件
首先我们来搞清楚一些关于Jquery插件的知识: 一.插件的种类: 封装对象方法的插件 这种插件是将对象方法封装起来,用于对通过选择器获取的jQuery对象进行操作,是最常见的一种插件 封装全局函数的 ...
- 自己编写jQuery插件之表单验证
自己编写jQuery插件之表单验证 吐个嘈先:最近状态不咋滴,真是什么都不想干,不想上班,做什么都没动力,觉得没意思.不想这样,不想这样,快让这种情绪消失吧,忽忽.... 表单验证在项目中用的还是比较 ...
- [置顶] 编写自己的JQUERY插件
如何编写自己的jquery插件 Jquery的插件主要分为三类: 1.封装对象方法的插件:大部分插件都是封装对象的插件 2.封装全局函数的插件:将独立的函数添加到jquery的命名空间之下.Jquer ...
- Javascript笔记:(实践篇)从jQuery插件技术说起-分析extend方法的源码(发现extend方法里有bug)(下篇)...
1.1 分析$.extend源码 在分析源码之前,我还要加一段s测试代码,代码如下: <script type="text/javascript"> $(doc ...
最新文章
- 电力系统【第3章:简单电力系统的潮流分布计算】
- ORACLE同义词源库锁表导致目标库删除操作报ora 02055 02049 02063 06512
- LiveVideoStack线上分享第三季(十一):Xilinx视频解决方案
- 使用Python开发小说下载器,不再为下载小说而发愁 #华为云·寻找黑马程序员#
- c语言编译器储存有什么用,C编译器怎么样对内存划分和使用
- vue 交互 HTML,Vue 自定义元素交互
- 隐藏桌面图标软件——CoverDesk for Mac免激活版
- 搜索引擎Elasticsearch,这篇文章给讲透了(建议收藏)
- ArcGIS中修改面图层中相邻面的公共边
- php fpm mysql 长链接_PHP Mysql数据库 长链接 短链接 (连接池 ?)
- Pandas高级教程之:Dataframe的合并
- 12个开放平台大家一起来玩
- 天才小毒妃 第952章 龙非夜挖的坑
- 虚拟机搭建web服务器
- JavaScript 每日一题 #8
- 苹果Mac系统虚拟打印机CAD输出PDF文档软件—pdfwriter
- Google资助人工智能研究机构
- excel拆分数据为多个工作表
- 计算机历史博物馆观后感:阿达·洛芙莱斯生平1
- HTTP状态码--1XX
热门文章
- 无法嵌入互操作类型“Microsoft.Office.Interop.Excel.ApplicationClass”。请改用适用的接口 ....
- ASP.NET 页面传值方法的一些事情儿。
- 自增、主键的优缺点(数据库)
- 网络模型一般是指 OSI 七层参考模型和 TCP/IP 五层参考模型。
- java底层实现分页
- UVa 10870 - Recurrences 矩阵快速幂
- 11 个创新的网站滑动效果设计案例展示
- 洛谷1091 合唱队形
- Mysql(8)_存储引擎之InnoDB
- E20180418-hm