不定义JQuery插件 不要说会JQuery


Posted in Javascript onMarch 07, 2016

一、导言

 

有些WEB开发者,会引用一个JQuery类库,然后在网页上写一写("#"),("#"),("."),写了几年就对别人说非常熟悉JQuery。我曾经也是这样的人,直到有一次公司里的技术交流,我才改变了自己对自己的看法。

二、普及JQuery知识

知识1:用JQuery写插件时,最核心的方法有如下两个:

$.extend(object) 可以理解为JQuery 添加一个静态方法。

$.fn.extend(object) 可以理解为JQuery实例添加一个方法。

基本的定义与调用:

/* $.extend 定义与调用
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
$.extend({ fun1: function () { alert("执行方法一"); } });
$.fun1();
/* $.fn.extend 定义与调用
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
$.fn.extend({ fun2: function () { alert("执行方法2"); } });
$(this).fun2();
//等同于
$.fn.fun3 = function () { alert("执行方法三"); }
$(this).fun3();

知识2:jQuery(function () { }); 与  (function ($) { })(jQuery);的区别:

jQuery(function () { });
//相当于
$(document).ready(function () { });
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
(function ($) { })(jQuery);
//相当于
var fn = function ($) { };
fn(jQuery);

jQuery(function () { });是某个DOM元素加载完毕后执行方法里的代码。

(function ($) { })(jQuery); 定义了一个匿名函数,其中jQuery代表这个匿名函数的实参。通常用在JQuery插件开发中,起到了定义插件的私有域的作用。 

三、开发JQuery插件标准结构

1、定义作用域:定义一个JQuery插件,首先要把这个插件的代码放在一个不受外界干扰的地方。如果用专业些的话来说就是要为这个插件定义私有作用域。外部的代码不能直接访问插件内部的代码。插件内部的代码不污染全局变量。在一定的作用上解耦了插件与运行环境的依赖。说了这么多,那要怎样定义一个插件的私有作用域?

//step01 定义JQuery的作用域
(function ($) {

})(jQuery);

别小看了这个作用域,就像c#定义一个类的class关键字一样重要。

2、为JQuery扩展一个插件:当定义好了JQuery的作用域后,最核心也是最迫切的一步就是为这个JQuery的实例添加一个扩展方法。首先我们为这个Jqury插件命名一个方法,叫easySlider,当在调用这个插件的时候,我们可以通过options来给这个插件传递一些参数。具体的定义方法看如下代码:

//step01 定义JQuery的作用域
(function ($) {
 //step02 插件的扩展方法名称
 $.fn.easySlider = function (options) {
  
 }
})(jQuery);

到现在为止,其实一个最简单的JQuery插件就已经完成了。调用的时候可以("#domName").easySlider({}),或者("#domName").easySlider({}),或者(".domName").easySlider({})或者更多的方式来调用这个插件。

3、设置默认值:定义一个JQuery插件,就像定义一个.net控件。一个完美的插件,应该是有比较灵活的属性。我们来看这段代码:<asp:TextBox ID="TextBox1" Width="20" Height="100" runat="server"></asp:TextBox>。  TextBox控件有Width和Height属性,用户在用TextBox时,可以自由的设置控件的Height和Width,也可以不设置值,因为控件自身有默认值。那准备开发一个JQuery插件时,在用户未指定属性时,应该有默认值,在JQuery可以分两步实现这样的定义,看如下代码step03-a,step03-b。

//step01 定义JQuery的作用域
(function ($) {
 //step03-a 插件的默认值属性
 var defaults = {
  prevId: 'prevBtn',
  prevText: 'Previous',
  nextId: 'nextBtn',
  nextText: 'Next'
  //……
 };
 //step02 插件的扩展方法名称
 $.fn.easySlider = function (options) {
  //step03-b 合并用户自定义属性,默认属性
  var options = $.extend(defaults, options);
 }
})(jQuery);

做程序的人都喜欢创新,改改变量名呀,换一个行呀这些。当看到用var defaults = {}来表示一个默认属性时,在自己写JQuery插件时就想着与众不同,所以用var default01 ={} ,var default02 ={}来表示默认属性了。然后默认属性名五花八门,越来越糟。所以建议在写JQuery插件时,定义默认属性时,都用defaults变量来代表默认属性,这样的代码更具有可读性。

有人看到这行代码:var options = $.extend(defaults, options),皱起眉头,表示不解。那我们先来看如下代码:

var obj01 = { name: "英文名:Sam Xiao", age: 29, girlfriend: { name: "Yang", age: 29} }
var obj02 = { name: "中文名:XiaoJian", girlfriend: { name: "YY"} };

var a = $.extend(obj01, obj02);
var b = $.extend(true, obj01, obj02);
var c = $.extend({}, obj01, obj02);

把代码拷贝到开发环境中,分别看一下a,b,c,d的值,就明白了var options = $.extend(defaults, options)的含义了。表示 options 去覆盖了defaults的值,并把值赋给了options。
在插件环境中,就表示用户设置的值,覆盖了插件的默认值;如果用户没有设置默认值的属性,还是保留插件的默认值。

4、支持JQuery选择器:JQuery选择器,是JQuery的一个优秀特性,如果我们的插件写来不支持JQuery选择器,确实是一个不小的遗憾。如了使自己的JQuery插件能支持多个选择器,我们的代码应该这样定义:

//step01 定义JQuery的作用域
(function ($) {
 //step03-a 插件的默认值属性
 var defaults = {
  prevId: 'prevBtn',
  prevText: 'Previous',
  nextId: 'nextBtn',
  nextText: 'Next'
  //……
 };
 //step02 插件的扩展方法名称
 $.fn.easySlider = function (options) {
  //step03-b 合并用户自定义属性,默认属性
  var options = $.extend(defaults, options);
  //step4 支持JQuery选择器
  this.each(function () {

  });
 }
})(jQuery);

5、支持JQuery的链接调用:上边的代码看似完美了,其实也不那么完美。到目前为止还不支持链接调用。为了能达到链接调用的效果必须要把循环的每个元素return

//step01 定义JQuery的作用域
(function ($) {
 //step03-a 插件的默认值属性
 var defaults = {
  prevId: 'prevBtn',
  prevText: 'Previous',
  nextId: 'nextBtn',
  nextText: 'Next'
  //……
 };
 //step02 插件的扩展方法名称
 $.fn.easySlider = function (options) {
  //step03-b 合并用户自定义属性,默认属性
  var options = $.extend(defaults, options);
  //step4 支持JQuery选择器
  //step5 支持链式调用
  return this.each(function () {

  });
 }
})(jQuery);

这样的定义才能支持链接调用。比如支持这样的调用:$(".div").easySlider({prevId:"",prevText:""}).css({ "border-width": "1", "border-color": "red", "border-bottom-style": "dotted" });

6、插件里的方法:往往实现一个插件的功能需要大量的代码,有可能上百行,上千行,甚至上万行。我们把这代码结构化,还得借助function。在第一点已经说了,在插件里定义的方法,外界不能直接调用,我在插件里定义的方法也没有污染外界环境。现在就尝试着怎么样在插件里定义一些方法:

//step01 定义JQuery的作用域
(function ($) {
 //step03-a 插件的默认值属性
 var defaults = {
  prevId: 'prevBtn',
  prevText: 'Previous',
  nextId: 'nextBtn',
  nextText: 'Next'
  //……
 };
 //step06-a 在插件里定义方法
 var showLink = function (obj) {
  $(obj).append(function () { return "(" + $(obj).attr("href") + ")" });
 }

 //step02 插件的扩展方法名称
 $.fn.easySlider = function (options) {
  //step03-b 合并用户自定义属性,默认属性
  var options = $.extend(defaults, options);
  //step4 支持JQuery选择器
  //step5 支持链式调用
  return this.each(function () {
   //step06-b 在插件里定义方法
   showLink(this);
  });
 }
})(jQuery);

步骤step06-a:在插件里定义了一个方法叫showLink(); 这个方法在插件外是不能直接调用的,有点像C#类里的一个私有方法,只能满足插件内部的使用。步骤step06-b演示了怎样调用插件内部的方法。

四、总结

开发只要形成了标准,然后再去阅读别人的代码就没有那么吃力了。

Javascript 相关文章推荐
用js来解决ajax读取页面乱码
Nov 28 Javascript
js单向链表的具体实现实例
Jun 21 Javascript
javascript:文字不间断向左移动的实例代码
Aug 08 Javascript
javascript中style.left和offsetLeft的用法说明
Mar 07 Javascript
js+html5实现的自由落体运动效果代码
Jan 28 Javascript
完美实现八种js焦点轮播图(上篇)
Jul 18 Javascript
Bootstrap CDN和本地化环境搭建
Oct 26 Javascript
关于Vue实现组件信息的缓存问题
Aug 23 Javascript
webpack配置之后端渲染详解
Oct 26 Javascript
对angular2中的ngfor和ngif指令嵌套实例讲解
Sep 12 Javascript
vuex vue简单使用知识点总结
Aug 29 Javascript
Vue初始化中的选项合并之initInternalComponent详解
Jun 11 Javascript
javascript数组去重小结
Mar 07 #Javascript
详解JS正则replace的使用方法
Mar 06 #Javascript
浅谈javascript中的call、apply、bind
Mar 06 #Javascript
一波JavaScript日期判断脚本分享
Mar 06 #Javascript
Node.js程序中的本地文件操作用法小结
Mar 06 #Javascript
JavaScript实现数据类型的相互转换
Mar 06 #Javascript
在React框架中实现一些AngularJS中ng指令的例子
Mar 06 #Javascript
You might like
基于asp+ajax和数据库驱动的二级联动菜单
2010/05/06 PHP
PHP之APC缓存详细介绍 apc模块安装
2014/01/13 PHP
详解PHP中的外观模式facade pattern
2018/02/05 PHP
php文件包含的几种方式总结
2019/09/19 PHP
ExtJS 2.0实用简明教程 之ExtJS版的Hello
2009/04/29 Javascript
ExtJS扩展 垂直tabLayout实现代码
2009/06/21 Javascript
Ext.MessageBox工具类简介
2009/12/10 Javascript
Jquery阻止事件冒泡 event.stopPropagation
2011/12/11 Javascript
jQuery写的日历(包括日历的样式及功能)
2013/04/23 Javascript
通过一段代码简单说js中的this的使用
2013/07/23 Javascript
在JavaScript中实现类的方式探讨
2013/08/28 Javascript
JS去除数组重复值的五种不同方法
2013/09/06 Javascript
php和js对数据库图片进行等比缩放示例
2014/04/28 Javascript
Node.js中的缓冲与流模块详细介绍
2015/02/11 Javascript
原生js与jQuery实现简单的tab切换特效对比
2015/07/30 Javascript
JS实现带关闭功能的阿里妈妈网站顶部滑出banner工具条代码
2015/09/17 Javascript
全系IE支持Bootstrap的解决方法
2015/10/19 Javascript
一个仿微博登陆邮箱提示框js开发案例
2016/07/28 Javascript
jQuery向父辈遍历的简单方法
2016/09/18 Javascript
jQuery中select与datalist制作下拉菜单时的区别浅析
2016/12/30 Javascript
Bootstrap栅格系统使用方法及页面调整变形的解决方法
2017/03/10 Javascript
Javascript面试经典套路reduce函数查重
2017/03/23 Javascript
简单的Vue异步组件实例Demo
2017/12/27 Javascript
微信小程序实现运动步数排行功能(可删除)
2018/07/05 Javascript
JavaScript实现拖拽盒子效果
2020/02/06 Javascript
零基础写python爬虫之打包生成exe文件
2014/11/06 Python
使用python批量读取word文档并整理关键信息到excel表格的实例
2018/11/07 Python
django-rest-framework 自定义swagger过程详解
2019/07/18 Python
django admin后管定制-显示字段的实例
2020/03/11 Python
Python selenium爬虫实现定时任务过程解析
2020/06/08 Python
美国折扣宠物药房:Total Pet Supply
2018/05/27 全球购物
高校毕业生自我鉴定
2013/10/27 职场文书
文案策划求职信
2014/04/14 职场文书
房屋所有权证明
2015/06/19 职场文书
小学班主任教育随笔
2015/08/15 职场文书
教师远程培训心得体会
2016/01/09 职场文书