之前写过jQuery插件的笔记
我一直觉得前面讲了一大堆闭包和三种插件封装模式有点冗余,那篇笔记我直到记录到后面才发现这事情很简单,想来想去还是觉得网上的一些文章把事情搞复杂了,其实这件事情很简单,所以我想按照自己的方式重新把这个问题阐述一遍。
我觉得学东西学的活的人都会从结果去倒推,比如说有些人学习音乐,先去练习演奏大量的曲目,然后再回来推敲这些曲子的作曲手法,这样更能事半功倍,而如果你从一开始就去研究作曲手法你可能连视奏能力都没有达到要求,这样做只会浪费时间。所以这篇博文的思路也是从结果倒推,要学习如何封装jQuery插件,首先要明白如何使用jQuery插件。
jQuery插件的使用方法非常简单,如果你用的足够多你就会发现其中的共性,简单来说就是以下3点:
1.插件都依赖于id
2.插件初始化的方法一般都是调用插件方法
3.插件方法的参数一般都是一个Object
我们以jQuery UI的datepicker为例,我们要把一个input输入框变成一个datepicker,方法如下:
<html> <head> <title>how to use datepicker plugin</title> <link rel="stylesheet" type="text/css" href="./css/jquery-ui.min.css" /> </head> <body> <!--input依赖于id--> <input type="text" id="datepicker1" readonly /> <input type="text" id="datepicker2" readonly /> <script src="./js/jquery-1.11.3.min.js"></script> <script src="./js/jquery-ui.min.js"></script> <script> $(function () { //调用插件方法初始化插件 //参数为Object类型 $("#datepicker1").datepicker({ minDate:0, onSelect:function(e){ alert("Hello,Datepicker!"); } }); //不带参数的datepicker初始化 $("#datepicker2").datepicker(); }); </script> </body> </html>
我们来总结一下就是,jQuery插件的使用方法一般来说就是
$("#id-selector").pluginFunctionName({ prop: value, method: function(){ //method code } });
弄清楚了这一点,那么我们就可以追本溯源地去编写jQuery插件了
首先我们要搞清楚编写插件时要具备的代码环境,这个环境不过多赘述,如有不懂请参看我开头提到的之前写的博文
<html> <head> <title>plugin</title> </head> <body> <div id="plugin"></div> <script src="./js/jquery-1.11.3.min.js"></script> <script> $(function () { $.fn.myPlugin = function () { //在这里编写插件 } }); $(function(){ //在这里调用插件方法 $("#plugin").myPlugin(); }); </script> </body> </html>
然后接下来要讲的是重点,我们一步一步来变化我们刚才写的代码
1.既然前面说到调用插件时有一个Object作为参数,这个Object设置了插件的很多内容,那么我们就把这个Object理解为一个设置项,即option,所以myPlugin这个方法要有一个options形参
<html> <head> <title>plugin</title> </head> <body> <div id="plugin"></div> <script src="./js/jquery-1.11.3.min.js"></script> <script> $(function () { $.fn.myPlugin = function (options) { } }); $(function(){ $("#plugin").myPlugin(); }); </script> </body> </html>
2.但是我们有时候调用插件的时候并不会带参数,而这个时候插件也能生效,这是因为插件的开发者们往往会事先写好一个Object作为默认的参数,当插件被调用时没有带参数,这个Object就会生效,我们将这个Object称为defaults
<html> <head> <title>plugin</title> </head> <body> <div id="plugin"></div> <script src="./js/jquery-1.11.3.min.js"></script> <script> $(function () { $.fn.myPlugin = function (options) { //设置defaults object var defaults = { Event:"click", msg:"Hello World!" }; } }); $(function(){ $("#plugin").myPlugin(); }); </script> </body> </html>
3.可是又有一些时候我们在调用插件的时候又会设置options里的一部分,而options的另一部分不设置,比如上面这个例子,我在调用myPlugin的时候如果写成这样
$("#plugin").myPlugin({ msg: "Ahhhhh~" });
我们只设置了msg,而Event被我们忽略了,那这个时候Event还是需要一个默认值,或者说,干脆就采用defaults里的那个click,
在这种情况下,我们使用jQuery提供的extend()方法来解决,它的作用是将两个不同的Object对象进行合并(Merge)
<html> <head> <title>plugin</title> </head> <body> <div id="plugin"></div> <script src="./js/jquery-1.11.3.min.js"></script> <script> $(function () { $.fn.myPlugin = function (options) { //设置defaults object var defaults = { Event:"click", msg:"Hello World!" }; //合并defaults和options var options = $.extend(defaults, options); } }); $(function(){ $("#plugin").myPlugin(); }); </script> </body> </html>
4.在上述步骤后我们需要预先设置好一些变量,比如获取this对,或者更进一步对插件进行事件绑定
<html> <head> <title>plugin</title> </head> <body> <div id="plugin"></div> <script src="./js/jquery-1.11.3.min.js"></script> <script> $(function () { $.fn.myPlugin = function (options) { //设置defaults object var defaults = { Event:"click", msg:"Hello World!" }; //合并defaults和options var options = $.extend(defaults, options); //获取this,对本例来说就是 $("#plugin") var $this = $(this); //进行事件绑定 $this.on(options.Event, function(e){ alert(options.msg); }); } }); $(function(){ $("#plugin").myPlugin(); }); </script> </body> </html>
最后这个简易的插件就算是完成了,我们可以带参数和不带参数来试一试
<html> <head> <title>simple node plugin example</title> </head> <body> <div id="hello">click me to say "Hello,World!"</div> <div id="bye">touch me to say "Goodbye,World!"</div> <script src="./js/jquery-1.11.3.min.js"></script> <script> $(function () { $.fn.myPlugin = function (options) { var defaults = { Event:"click", msg:"Hello World!" }; var options = $.extend(defaults, options); var $this = $(this); $this.on(options.Event, function(e){ alert(options.msg); }); } }); $(function(){ $("#hello").myPlugin(); $("#bye").myPlugin({Event:"mouseover",msg:"Goodbye,World!"}); }); </script> </body> </html>
然而这里还有一个问题,如果我们想要插件多一些DOM层次呢?比如Bootstrap的panel面板,有title,有content,而且点击title能够切换显示隐藏,这应该怎么写呢?
其实思路也很简单,无非就是获取到这个插件最外层(也就是id那一层)的子节点,然后对这些子节点进行绑定,我自己试着写了一个简单的panel插件,个人认为简单易懂,所以直接贴上来,不作解释。
<html> <head> <title>multi node plugin example</title> <style> .panel{width:350px;} </style> </head> <body> <div class="panel" id="test"> <div class="title"> <p>I am Title,click me to show the content</p> </div> <div class="content"> <p>I am Content</p> <p>I wanna say</p> <p>Hello,World!</p> </div> </div> <script src="./js/jquery-1.11.3.min.js"></script> <script> $(function () { $.fn.panel = function (options) { var defaults = { titleFontColor:"red", titleBackgroundColor:"#eeeeee", contentFontColor:"blue", contentBackgroundColor:"#e5e5e5" }; var options = $.extend(defaults, options); var $this = $(this); var $title = $this.children("div.title"); var $content = $this.children("div.content"); $title.css({ color: options.titleFontColor, background:options.titleBackgroundColor }); $content.css({ color: options.contentFontColor, background:options.contentBackgroundColor }); $title.on("click", function(){ $content.toggle(); }); } }); $(function(){ $("#test").panel({contentFontColor:"#000000"}); }); </script> </body> </html>
相信看完这篇文章后,你就能完全理解如何去编写一个jQuery插件了!