这个故事得从一个弹窗开始说起。。。
从前,我曾想做一个精美的弹窗,好的,那最先我需要一个最基础的html代码结构:
此刻,我们需要写一些简单的js代码来封装这个插件的功能,像这样:
然后,我们做一些简单的修饰细节,这个弹窗就完成了。。。
好了,开始正经。。。
js插件是什么?和js组件又有什么区别呢?
答:其实我们大可不必在网上去读那些个大神的高深解读,我们只要知道,插件是衍生品,是在某一个完整功能的前提下的某种扩展,组件则是独立功能体,不依靠任何功能基础和代码基础。
为什么要写js插件?
答:js插件其实是把某种功能(注意,此处的意思是某个操作过程)封装起来,以便多次调用,并且减少代码量,实现代码的优化管理。
为什么要写组件?
答:大型js工程里,我们需要实现js代码逻辑合理的组织,代码功能间相互关联且独立的关系,依靠几个核心功能结构从而实现大量其他功能,这就是组件存在的意义,侧面来看,组件是js这门非面向对象语言最容易和面向对象对接的一个契机,因为,所有人写得面向对象组件都是一样的。
今天咱们要学习的就是——js插件
首先,插件需要一个容器来包含你的所有代码,从而避免与别人的代码冲突(之前聊过的命名空间)
;(function($){ })(jQuery);
$和后面那个jQuery不赘述。
通过这个自执行函数,我们就能拥有一个封闭的作用域了,也能够把这个作用域作为一个命名空间来使用,当然真正的命名空间肯定不在这里,而是jQuery对象本身。
接下来,我们要做的就是,在这个自执行函数中为jquery的命名空间添加我们的插件:
;(function($){ $.fn.myDialog=function(){ } })(jQuery);
好了,有了这两步,我们的插件形式基本已经完成了,你的插件被调用的时候应该是这样的:
$("#box").myDialog();
现在,咱们就正式的开始书写插件了。
首先解释一个问题:
插件代码中的this,代表了调用这个jquery插件的对象,而不再是平时jquery方法中的this了(jquery方法中的this往往代表的是dom对象。)
我们来实现一个小功能,顺便也能证明一下this的问题:
;(function($){ $.fn.myDialog=function(){ //实现输出对象的高度并且改变对象的底色 console.log(this.height()); this.css("background","red"); } })(jQuery);
从代码中可以看到,这个插件现在具备了输出对象高度和修改对象背景颜色的功能。
并且从中可以反应出一个问题,这里面的this就是调用插件的对象(jquery),而不是dom对象。
保证插件的可连续性(链式调用)
;(function($){ $.fn.myDialog=function(){ //实现输出对象的高度并且改变对象的底色 console.log(this.height()); this.css("background","red"); return this; } })(jQuery);
这样的话,我们就可以让插件实现jquery的链式调用了,是不是觉得很棒。
不得不说的一件事,千万不要以为所有的插件都需要链式调用,其实并非如此,如果你的插件并不需要返回什么值的话,你完全可以保持插件的可连续性,如果你的插件需要返回某些特定的值的时候,就不需要这样做了。
现在,我们来用学到的知识写一个很简单的插件——模块拖拽
提一下,插件的思想其实跟以前函数式编程有点类似,只不过插件封装的更好,扩展性更好罢了。
html代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>插件基础1</title> <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script> <script type="text/javascript" src="js/dialog.js"></script> <style type="text/css"> #box{ width: 200px; height: 100px; background: blue; position:absolute; cursor: move; } </style> <script type="text/javascript"> $(function(){ $("#box").boxMove({ callback:function(){ alert("拖拽成功"); } }); }) </script> </head> <body> <div id="box"></div> </body> </html>
js代码:
;(function($){ $.fn.boxMove=function(){ //配置参数整合 return this.each(function(){ $(this).mousedown(function(e){ //计算鼠标指针处在被移动模块的什么位置 var cliX=e.pageX-$(this).position().left, cliY=e.pageY-$(this).position().top; $this=$(this); //计算出被移动模块应该移动的位置 $(document).mousemove(function(e){ $this.css({ left:e.pageX-cliX, top:e.pageY-cliY }); }); // $(document).mouseup(function(){ $(document).off("mousemove"); $(document).off("mouseup"); }); }); }); } })(jQuery);