学习做一个jq的插件,并用grunt构建打包。

这个插件的功能很简单,让选择器匹配元素运动到某个指定位置。有兴趣学习做jq插件的同学可以看这个教程-》http://i5ting.github.io/How-to-write-jQuery-plugin/build/jquery.plugin.html,最好先研究过jq的源码,这样学起来比较容易,顺便也可以加深自己的jq源码的理解。

以下是过程。

确定功能需求后,将还未封装成插件的代码写出来(写到这里我发现我没有留最开始那份代码……所以略过)。在写代码的时候要留意什么参数是必须由外部提供的,除此之外的代码我们应该全部封进插件,让我们的插件更独立,耦合性更低,配置起来也比较简单。对本文的插件来说,除了移动的元素要从外界传进来,还需要传入移动的终点和起点,其中起点其实可以在插件内部设置。

/**
* 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
        }
     }

接着写实现插件功能的业务逻辑。

/**
* 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() {
        	
        });
    }

因为这个插件的功能比较简单,这样把参数初始化和业务逻辑分离成单独方法看起来有点小题大作,但我觉得这是一个良好的习惯,一是提高代码可读性,二也方便我们以后对插件功能的扩展,易维护升级。

接下来我们套用jq插件的模板。这里说一下 jQuery支持的2种插件方式,为jQuery写插件其实就是扩展jQuery的方法,扩展方式有两种,一个是基于类扩展,一个是基于对象(原型)扩展。

基于类扩展

基于类扩展可以理解为 为jQuery类添加静态方法,模板为

$.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,结果如下:

jquery文件打包到服务器 jquery项目怎么打包_python

进入项目文件夹,创建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文件夹里。

 

(完)