侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

javascript的瑞士军刀: ns.js

2024-05-12 星期日 / 0 评论 / 0 点赞 / 89 阅读 / 16095 字

目前这套工具包已经稳定运行于生产环境半年,日均10WPV。 基于这套js,哪怕你是个菜鸟也可以很轻松愉快地加入到JS前端开发的世界啦! 废话不多说,上代码: /** * @author LiNan

目前这套工具包已经稳定运行于生产环境半年,日均10W PV。

基于这套js,哪怕你是个菜鸟也可以很轻松愉快地加入到JS前端开发的世界啦!

废话不多说,上代码:

/** * @author  LiNan   * @company kidswant Co. Ltd. * @email   [email protected] * @version 2016-4-13  * @remark  需要依赖JQuery库 * 我的JS命名空间的解释: * 简称	 	释义 * NS		namespace的缩写,表示通用的命名空间。这里面放置的全部是工具类。当你不确定你的工具类方法应该放在什么地方的时候,你就可以将其放在这里。 * 			其中,NS里面放置的是基础性的通用方法,便于在任何的业务代码中方便地调用。 * 			而NS.webExt里面放置的是Web领域方向专用方法。其相比通用方法,更加领域化。 * 			NS和NS.webExt之间的关系,好比JAVA SE与JAVA EE之间的关系。前者是基础,是基石,是赖以生存的根基。后者是前者的有力补充、重要扩充,是资料片。 * 			好的设计模式,必然是经久不衰的!在实践的过程中,不断地提炼出结构化、模块化、可复用的、通用性强的代码,形成自己的个性代码库,从长远来看,都是超值的。 *  * PB		pubSub,发布订阅设计模式的一个实现。利用此种模式,可以方便的为指定的对象绑定事件、触发事件。 * 			 *///这里是我的专属命名空间var NS = {	browser:{		versions : function() {			var u = navigator.userAgent, app = navigator.appVersion;			return { // 移动终端浏览器版本信息				iOS : !!u.match(//(i[^;]+;( U;)? CPU.+Mac OS X/), 		// ios终端				android : u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, 	// android终端或uc浏览器				iPhone : u.indexOf('iPhone') > -1, 			// 是否为iPhone或者QQHD浏览器				iPad : u.indexOf('iPad') > -1				// 是否iPad			};		}()},	/**	 * 写cookies	 * name键	 * value值	 */		setCookie:function(name,value,expireDays){		var Days = 36000;//(默认为永远不过期)写入之后有效期设置为100年,也就是相当于永不过期		if(expireDays){			//假如传了过期时间这个参数			Days = expireDays;		}		var exp = new Date();    		exp.setTime(exp.getTime() + Days*24*60*60*1000);		document.cookie=(name + "="+ escape(value) + ";expires=" + exp.toGMTString()+";path=/" +(NS.cookieDomain? (";domain="+ NS.cookieDomain):"")); //设置cookie的键值对信息以及过期信息 (指定path真的很重要!) 	},	//写cookie。该cookie的生命周期为:session	setCookieInSession:function(name,value){		var isIE=!-[1,];//判断是否是ie核心浏览器  		if(isIE){  			document.cookie = (name + "="+ escape(value) + ";expires=At the end of the Session;path=/" +(NS.cookieDomain? (";domain="+ NS.cookieDomain):""));//设置cookie的键值对信息以及过期信息 (指定path真的很重要!) 		}else{			document.cookie = (name + "="+ escape(value) + ";expires=Session;path=/" +(NS.cookieDomain? (";domain="+ NS.cookieDomain):""));//设置cookie的键值对信息以及过期信息 (指定path真的很重要!) 		}	},	//读取cookies	getCookie:function(name){   		var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");   		if(arr=document.cookie.match(reg)){			return unescape(arr[2]);		}else{			return null;   		}	},	//删除cookies   	delCookie:function(name){   		var exp = new Date();   		exp.setTime(exp.getTime() - 1);//将过期时间设置为上一毫秒   		var cval=this.getCookie(name);   		if(cval!=null){			document.cookie= (name + "="+cval+";expires="+exp.toGMTString()+";path=/"+(NS.cookieDomain? (";domain="+ NS.cookieDomain):""));//若能取到这个cookie的键值对,那么就将其设置为过期    (指定path真的很重要!) 		}	},	//删除cookies,未指定域名的	delCookieWithoutDomain:function(name){		var exp = new Date();   		exp.setTime(exp.getTime() - 1);//将过期时间设置为上一毫秒   		var cval=this.getCookie(name);   		if(cval!=null){			document.cookie= (name + "="+cval+";expires="+exp.toGMTString()+";path=/");//若能取到这个cookie的键值对,那么就将其设置为过期    (指定path真的很重要!) 		}	},	//判断某个字符串是否为空	isNull:function(obj){		if(!obj || obj.length ==0){			return true;		}		return false;	},	//判断是否为空	isEmpty:function(obj){		return this.isNull(obj);	},	/**	 * 是否不为空	 */	isNotEmpty:function(obj){		return !this.isNull(obj);	},	//某个数组中是否包含某个元素	contains:function(element,array){		if(this.indexOf(element,array)!=-1){			return true;		}		return false;	},	//返回某个元素在数组中的位置	indexOf:$.inArray,	/**	 * 删除数组中某个索引的数据	 * @param idx	 * @param array	 * @returns	 */	removeIdx:function(idx, array){		if(isNaN(idx)||idx>array.length){			return false;		}		for(var i=0,n=0; i<array.length; i++){			if(array[i]!=array[idx]){				array[n++]=array[i];			}		}		array.length-=1;//如果数组已经没元素了,再删除就会报错!		return array;	},		/**	 * 判断某个字符串是不是以某个字符串开头	 * 为何要写这个方法?因为令人无语的微信浏览器竟然不支持该方法啊!!!	 * @param original  原有的字符串	 * @param str    待搜索的字符串	 * @returns {Boolean}	 */	startsWith:function(original,str){          if(str==null||str==""||original.length==0||str.length>original.length){        	return false;          }  		if(original.substr(0,str.length)==str){			return true;  		}else{			return false;  		}  		return true;        },      /**       * 判断某个字符串是不是以某个字符串结尾       * @param original       * @param str       * @returns {Boolean}       */	endWith:function(original,str){  		if(str==null||str==""||original.length==0||str.length>original.length){			return false;  		}  		if(original.substring(original.length-str.length)==str){			return true;  		}else{			return false;  		}  		return true;  	  },        	//返回短名称	shortName:function(str, maxLength){		if(str && str.length>0){			var len = str.length;			if(len<=maxLength){				return str;			}else{				return (str.substr(0,maxLength)+"...");			}		}else{			return "";		}	},	//检查是否是数字	checkNumber:function(value){		var reg = /^[1-9]/d*$/;		if("0" == value || reg.test(value)){			return true;		}else{			return false;		}	},	//将指定map的指定的key初始化成空array	initMapArray:function(){		var len = arguments.length;//可变参数的方法		if(len==0 || len ==1){			return;		}		var map = arguments[0];		for(var i=1;i<arguments.length;i++){			var paramName = arguments[i];			map[paramName]=[];		}	},	//匿名	anoym:function(name){		if(!name || name.length ==0){			return "***";		}		var length = name.length;		if(length == 1){			return (name +"***");		}else{			return (name[0]+"***"+name[name.length-1]); 		}	},	/**	 * 动态加载脚本	 * 不推荐使用,因为这样加载的脚本会到最后才执行。如果该脚本被其他脚本依赖,则不推荐这样的方式	 * @param script	 */    loadScript:function(url) {        var content = '<script type="text/javascript" src="' + url + '"></script>';        document.writeln(content);    },    /**     * 动态加载样式     * @param url     */    loadCss:function(url) {        var content = '<link rel="stylesheet" type="text/css" href="'+url+'"/>';        document.writeln(content);    },	//转换为用于显示用的字符串(去除undefined等等不合理的显示)	toStr:function(obj){		if(this.isNull(obj)){			return "";		}		return obj;	},    //兼容方式获取滚动条距离顶部的距离    getScrollTop:function(){    	var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;		return scrollTop;    },    //兼容方式设置滚动条距离顶部的距离    setScrollTop:function(scroll_top) {    	document.documentElement.scrollTop = scroll_top;    	window.pageYOffset = scroll_top;    	document.body.scrollTop = scroll_top;    },    /**     * 获取两个日期的天数差(起始时间-结束时间)      */    getDateDiffDays:function(startDate,endDate){          var startTime = new Date(Date.parse(startDate.replace(/-/g,"/"))).getTime();//得到毫秒数             var endTime = new Date(Date.parse(endDate.replace(/-/g,"/"))).getTime();             var dates = Math.abs((startTime - endTime))/(1000*60*60*24);//取绝对值             return dates;        },	//防重复提交的事件注册表	//用于检测某个事件是否已经在队列里先行一步了	_timerReg:{},	/**	 * 防止快速点击所导致的重复提交	 * @param id 标记,用于区分是否是同一种业务场景	 * @param fn 回调函数	 * @param wait 等待的毫秒数	 * @returns	 */	preventDuplicateSubmission:function(id, fn, wait){		if(!wait){			wait=300;//默认延迟时间是300毫秒		}		if (NS._timerReg[id]) {			console.log("检测到重复点击...");	        window.clearTimeout(NS._timerReg[id]);	        delete NS._timerReg[id];	    }	    return NS._timerReg[id] = window.setTimeout(function() {	        fn();	        delete NS._timerReg[id];	    }, wait);	},	/**	 * 将对象保存到localStorage	 * @param key	 * @param obj	 */	saveLocalStorageObj:function(key,obj){		if(localStorage){			localStorage[key] = JSON.stringify(obj);		}	},	/**	 * 从localStorage读取出对象	 * @param key	 */	readLocalStorageObj:function(key){		if(localStorage && localStorage[key]){			if(NS.isNotEmpty(localStorage[key])){				return JSON.parse(localStorage[key]);			}		}		return null;	},	/**	 * 指定的Url中,如果不存在某个参数,则添加该参数	 */	appendUrlParamIfNotExist:function(url,name,value){		if(!this.urlHasParam(url,name)){			//没有参数,则加上参数。有参数,则什么都不做			url = this.urlAppendParam(url,name,value);		}		return url;	},	/**	 * 给指定的url增加参数	 * @param url	 * @param name	 * @param value	 */	urlAppendParam:function(url,name,value){		url+=((url.indexOf("?")==-1?"?":"&")+name+"="+value);		return url;	},	//某个url中,是否含有某个参数	urlHasParam:function(url,name){		var paramArray = this.getUrlParamArray(url);		if(this.contains(name,paramArray)){			return true;		}else{			return false;		}	},	/**	 * 获取指定URL的参数的数组	 * 只要是在这个URL中出现过的参数,都可以算在里面	 * @param url	 * @returns {Object}	 */	getUrlParamArray:function(url) {	   var retArray =[];	   if (url.indexOf("?") != -1) {	      var str = url.substr(url.indexOf("?")+1);	      strs = str.split("&");	      for(var i = 0; i < strs.length; i ++) {//	         theRequest[strs[i].split("=")[0]]=(strs[i].split("=")[1]);				retArray.push(strs[i].split("=")[0]);	      }	   }	   return retArray;	},	/**	 * 替换所有字符	 * @param str 	 * @param reallyDo 想要替换的	 * @param replaceWith 替换成的	 * @param ignoreCase 是否忽略大小写	 * @returns	 */	replaceAll:function(str, reallyDo, replaceWith, ignoreCase) {  	    if (!RegExp.prototype.isPrototypeOf(reallyDo)) {  	        return str.replace(new RegExp(reallyDo, (ignoreCase ? "gi": "g")), replaceWith);  	    } else {  	        return str.replace(reallyDo, replaceWith);  	    }  	}};/** * @author LiNan 2016-4-13 * 发布、订阅模式的工厂类<br> * 如果想用,请实例化,例如:var pubSub = new NS.PubSub(); */NS.PubSub = function(){	//是否开启日志	this.debugMode=true;	/**	 * 事件处理器列表	 * 结构如下:	 * 	click:[functionA, functionB, functionC, ...]	 *  blur:[functionD, functionE, functionF, ...]	 *  ...	 */	this.handlers={};	/**	 * 为某种事件名成绑定(追加)一个新的事件监听器<br>	 * 例如,PubSub.on("click",function(){ doSth...})	 */	this.bind=this.on=function(eventType, handler) {		if (!(eventType in this.handlers)) {			// 若还从未绑定过此种事件类型,例如click事件			this.handlers[eventType] = [];// 为该种类的事件类型初始化一个空的处理器数组		}		// 此时,this.handlers[eventType]可能是一个空数组,也可能是一个已经有了若干个处理器的数组了!		this.handlers[eventType].push(handler);		if (this.debugMode) {			console.log("成功绑定" + eventType + "事件!");		}		// 返回this,便于后续的继续的链式调用		return this;	};	/**	 * 移除事件处理器	 */	this.clear = this.off = function(eventType, handler) {		if(eventType){			//对指定的事件类型进行移除			if (handler) {				// 如果传参了,那么只移除指定的handler				this.handlers[eventType].pop(handler);				if (this.debugMode) {					console.log("成功解除指定参数类型的" + eventType + "事件!");				}			} else {				// 移除所有的handler				this.handlers[eventType] = [];				if (this.debugMode) {					console.log("成功解除所有的" + eventType + "事件!");				}			}		}else{			//移除所有的事件类型			for(var et in this.handlers){				 if (typeof(et)=="function"){					 //是一个function,不可以删除 				 }else if(typeof(et) =="string"){					 //可以删除					 delete this.handlers[et];				 }			}		}		return this;	};	/**	 * 打印所有的事件列表	 */	this.show=this.view=function(eventType) {		if(eventType){			if(this.handlers[eventType]){				console.log("当前绑定" + eventType + "类型的事件回调函数列表为:/n"+ this.handlers[eventType]);			}		}else{			for(var p in this.handlers){				 if (typeof(p)=="string"){					 console.log("当前绑定" + p + "类型的事件回调函数列表为:/n"+ this.handlers[p]);				 }			}		}		return this;	};	/**	 * 手工触发某个事件<br>	 * 例如:PubSub.emit("click","param1","param2");<br>	 * 那么,就会将PubSub对象上面绑定的所有的click事件函数依次触发(调用)一遍	 */	this.fire = this.trigger = this.emit=function(eventType) {		// 从第一个参数往后截取所有的后续参数的数组,例如,此例中,就是["param1","param2"]		var handlerArgs = Array.prototype.slice.call(arguments, 1);		if(this.handlers[eventType] && this.handlers[eventType].length>0){			for (var i = 0; i < this.handlers[eventType].length; i++) {				// this.handlers[eventType][i]就是那个绑定的函数,调用该函数,并传入参数,即可				this.handlers[eventType][i].apply(this, handlerArgs);			}		}else{			if (this.debugMode) {				console.log("未绑定任何 【"+ eventType+"】 事件!忽略调用!");			}		}		// 返回this,便于后续的继续的链式调用		return this;	}};//一个开箱即用的发布订阅模式的实例,你可以立刻使用它!var PB = new NS.PubSub();

 

想要上手使用很容易:

判断一个变量是否为空                                NS.isEmpty(param)

获取cookie名称为uid的值                            NS.getCookie("uid")

读取LocalStorage对象                                NS.readLocalStorageObj("aaa")

判断数组中是否含有某个元素                     NS.contains('a',['a','b'])

...

 

想要基于ns.js做扩展也很容易:

NS.webExt={    showTip:window.showTip}//将新增的方法全部扩展至主方法中$.extend(NS, NS.webExt);

这样,扩展的方法也可以直接通过 NS.showTip() 进行调用啦!

是不是很方便呀!

广告 广告

评论区