学习作一个jq的插件,并用grunt构建打包。html
这个插件的功能很简单,让选择器匹配元素运动到某个指定位置。有兴趣学习作jq插件的同窗能够看这个教程-》http://i5ting.github.io/How-to-write-jQuery-plugin/build/jquery.plugin.html,最好先研究过jq的源码,这样学起来比较容易,顺便也能够加深本身的jq源码的理解。前端
如下是过程。node
肯定功能需求后,将还未封装成插件的代码写出来(写到这里我发现我没有留最开始那份代码……因此略过)。在写代码的时候要留意什么参数是必须由外部提供的,除此以外的代码咱们应该所有封进插件,让咱们的插件更独立,耦合性更低,配置起来也比较简单。对本文的插件来讲,除了移动的元素要从外界传进来,还须要传入移动的终点和起点,其中起点其实能够在插件内部设置。jquery
/** * init_moveTo_config: 初始参数配置 * param: * @obj: 移动的元素 * @opts: 用户配置参数 */ function init_moveTo_config (obj,opts){ /* srcPosition 初始位置*/ var srcPosition = { left:$(obj).position().left, top:$(obj).position().top } /* 最终肯定的位置*/ opts = { left:opts.left?opts.left:srcPosition.left, top:opts.top?opts.top:srcPosition.top, speed:opts.speed } }
接着写实现插件功能的业务逻辑。git
/** * init_moveTo_event: 插件业务逻辑 * param: * @obj: 移动的元素 * @opts: 用户配置参数 */ function init_moveTo_event (obj,opts) { $(obj).animate( { left:opts.left+"px", top:opts.top+"px", opacity:'1' },opts.speed,"easeInOutBack",function() { }); }
由于这个插件的功能比较简单,这样把参数初始化和业务逻辑分离成单独方法看起来有点小题大做,但我以为这是一个良好的习惯,一是提升代码可读性,二也方便咱们之后对插件功能的扩展,易维护升级。github
接下来咱们套用jq插件的模板。这里说一下 jQuery支持的2种插件方式,为jQuery写插件其实就是扩展jQuery的方法,扩展方式有两种,一个是基于类扩展,一个是基于对象(原型)扩展。npm
基于类扩展json
基于类扩展能够理解为 为jQuery类添加静态方法,模板为windows
$.myplugins={ plugin_a: function( args ) { //plugin_a代码.. }, plugin_b: function( args ) { //plugin_b代码.. } //...更多插件定义 };
基于类的扩展通常用于制做全局工具类,好比:性能优化
$.strTools = { trim:function( str ) { return str.replace( /\s+/g, "" ); } } $.strTools.trim(' hello world ');
ps: 将插件封装在一个独立的命名空间(如myPlugins)能够避免命名空间内函数的冲突。
基于对象扩展
相对于基于类扩展,而基于对象扩展的插件有选择器,且能够传入用户配置参数,复用程度比较高,在实际中应用很是普遍。
基于对象扩展能够理解为 为jQuery对象添加插件方法,模板为:
;(function($) { /** * init_xxx_config: 初始参数配置 * param: * @obj: 命中元素(可选参数) * @opts: 用户配置参数 */ function init_xxx_config (opts,[obj]){ //对初始参数的处理 } /** * init_xxx_event: 插件业务逻辑 * param: * @obj: 命中元素 * @opts: 用户配置参数 */ function init_moveTo_event (opts,obj) { //编写插件业务逻辑 } $.fn.xxx = function (options) { /* options:用户的配置参数*/ var opts = $.extend({},$.fn.moveTo.defaults,options); return this.each(function() { var obj = $(this);//保存当前选择器匹配对象指针 init_xxx_config (opts,[obj]);//调用初始化参数 init_xxx_event (opts,obj);//调用业务逻辑 }); }; /* defaults :插件默认的配置参数*/ $.fn.moveTo.defaults = { //... }; })(jQuery);
还有另外一个模板
(function($){ $.fn.extend({ pluginName:function(opt,callback){ } }) })(jQuery);
研究过jq源码的同窗应该看过这段代码jQuery.fn = jQuery.prototype ={...},也就是说jQuery.fn.extend(object); 是对jQuery.prototype扩展,就是为jQuery类添加公共方法,jQuery类的实例均可以共享这个函数。
至此个人插件编码就完成了。接下来学习使用grunt来构建打包。至于为何要用grunt不用我来解释了...
yahoo军规讲到前端性能优化的一点就是压缩js代码,虽然个人这份插件代码很少(1.84 KB),压缩以后变成700多字节,相差看起来不大,可是若是对其余比较大的js文件,压缩效果就很明显了,就拿jq来讲,jq未压缩文件大概是268k,压缩后(jquery.min.js)只有85k左右!我此次用grunt主要就是压缩代码。
顺便说一下个人系统环境是windows。
确保npm跟node装好后,安装grunt-CLI: npm install -g grunt-cli ,安装完毕后cmd敲grunt,结果以下:
进入项目文件夹,建立package.json和gruntFile.js文件。package.json管理项目信息(项目名称,版本,做者,依赖列表),当你将项目发布时,通常不会把node_modules里的依赖包也放上去,若是那样作可能你的项目就太大了,上传和下载都不方便,那得到你项目的人要怎么安装项目须要的依赖包呢,很简单,在项目文件夹敲npm install命令就能够安装全部package.json中声明的依赖了,注意建立完package.json后要添加一些必要的信息,如devDependencies,否则使用npm install命令会没法查找和更新依赖从而出错。gruntFile.js则用来指导grunt作什么,如今直接建立一个空的gruntFile.js文件就行了。
个人packege.json文件
{ "name": "moveToAnimate", "version": "1.0.0", "author": "jsal", "devDependencies": { } }
准备好package.json和gruntFile.js后(注意package.json内容的格式要正确),安装grunt到该项目(不是全局安装) npm install grunt --save-dev 。“—save-dev”的意思是,在当前目录安装grunt的同时,顺便把grunt保存为这个目录的开发依赖项,也就是说会添加进packege.json的"devDependencies"的值里面。
安装完毕后输入grunt,结果以下(请忽略个人文件路径,那只是我我的的测试~)
表示咱们的grunt安装好了,可是由于咱们没有指定它要作什么,因此才是上面的结果。
接下来安装grunt的官方插件,uglify插件,用来压缩js代码。
npm install grunt-contrib-uglify --save-dev
ps:带有contrib的插件表示是grunt官方维护的插件。安装完毕后package.json就会又多一个依赖信息:"grunt-contrib-uglify": " 安装的版本号 "。
接下来配置gruntFIle.js,让grunt使用uglify为咱们压缩代码 。
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), //grunt参考的package.json配置文件的路径 uglify: { //uglify插件的配置参数 options: { stripBanners: true, banner: '/*!<%= pkg.name %>-<%= pkg.version %>.js <%= grunt.template.today("yyyy-mm-dd") %>*/\n' },//设置了banner后banner的内容会出如今压缩代码的最开始的地方 //<%= pkg.name %> 得到了package.json中配置的name参数 build: { src: 'src/moveTo.js', //要压缩的源文件 dest: 'build/<%= pkg.name %>-<%= pkg.version %>.js.min.js' //设置压缩后的目标路径及文件名 } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); //加载grunt-contrib-uglify模块 grunt.registerTask('default',[ 'uglify']); //执行uglify }
配置无误后再次输入grunt就能执行压缩动做啦,压缩完的文件放在配置的build文件夹里。
(完)