js平常开发-经常使用方法封装

在咱们平常开发过程当中,咱们本身常常会写大量的方法,也就是function,来封装一些经常使用功能,来知足咱们的开发须要。本篇文章呢,我把本身这几年前端开发写的一些可复用的方法分享出来,与你们一块儿学习探讨:前端

数据类型检测方法

众所周知js的typeOf或者instanceof在数据类型检测上都有局限性,该方法检测返回值是以字符串形式: [object String],[object Array],[object Function],[object Object],[object Null],[object RegExp],[object Undefined],[object Symbol] `android

function dataType (type){	// 检测数据类型
    var dataType = Object.prototype.toString;
        return dataType.call(type)
}
复制代码

`ios

检测返回数据是否为空数据

咱们平常开发中,数据多数是后端返回来的,咱们对因而否有返回来数据作相应的处理,该方法接收一个参数data,返回一个布尔值,是否为空数据,true为空,false为否: `es6

function isEmpty(data){ //是否为空数据
    //null,undefined,'',"",{},[],[{}] 匹配到这些值时,都是返回true
    if(data==='' || data==="" || data==='undefined' || data===undefined || data===null)
        {return true}
    if(JSON.stringify(data)=='{}' || JSON.stringify(data)=='[]' || JSON.stringify(data)=='[{}]')
        {return true}
    return false
复制代码

} `web

多维数组拉伸一维数组方法

多维数组指的是咱们处理的数据里,数组里面还嵌套有数组,有时候咱们的代码逻辑须要不数组拉伸维一维的数组来处理,这就是此方法的做用了,该方法只接受一个参数,该参数就是个数组,返回也是个数组: `element-ui

var arry = [11, 7, 5, [1, 9], 3, [15, [13, 17]]];
	function flattenDepth(arry){
			let result = [];
			arry.map(item => {
				if (Array.isArray(item)) {  // es6语法检测当前是不是数组
					result.push(...flattenDepth(item))  // 此处是用了es6语法,扩展运算符
				} else {
					result.push(item)
				}
			})
			return result;
		}
复制代码

`json

URL解析方法

对url的解析,咱们的主要目的都是获取url上的参数,也就是query值,该方法接收一个url参数,会返回一个参数对象: `canvas

function queryUrl(url) {  // 解析url数据传参
	var objUrl = {};
	var urlData = url.split('?')[1];
	if (urlData) {
		var urlArr = urlData.split('&');
		for (var i = 0, len = urlArr.length; i < len; i++) {
			var curArr = urlArr[i].split('=');
			objUrl[curArr[0]] = curArr[1]
		}
		return objUrl
	}    	
}
复制代码

`后端

转千位符方法

转千位符是咱们对数字处理的一个方法,该方法接收一个数字: `数组

function toThousands1(num) {	//转千位符 方法1
	var num = Number(num).toFixed(2);
	var n = num.indexOf('.');
	var str1 = num.slice(0, n), str2 = num.slice(n, num.length), result = '';
    while (str1.length > 3) {
        result = ',' + str1.slice(-3) + result;
        str1 = str1.slice(0, str1.length - 3);
    }
    if (str1) { result = str1 + result; }
    return result+str2;
}

function toThousands2(num) {	// 转千位符 方法2
	var num = Number(num).toFixed(2);   //若是你想把你转的数保留3位小数,把2改3就行了
	var n =	num.indexOf('.');
	var str1 = num.slice(0, n), str2 = num.slice(n, num.length);
    var result = '', counter = 0;
    for (var i = str1.length - 1; i >= 0; i--) {
        counter++;
        result = str1.charAt(i) + result;
        if (!(counter % 3) && i != 0) { result = ',' + result; }
    }
    return result+str2;
}
复制代码

`

数字金额转大写方法

对数字转大写,特别是开发金融类型的web或者h5时,使用最多,该方法接收一个参数,就是要转的数字, `

function convertCurrency(money) {	// 金额数字转大写
		//汉字的数字
		var cnNums = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖');
		//基本单位
		var cnIntRadice = new Array('', '拾', '佰', '仟');
		//对应整数部分扩展单位
		var cnIntUnits = new Array('', '万', '亿', '兆');
		//对应小数部分单位
		var cnDecUnits = new Array('角', '分', '毫', '厘');
		//整数金额时后面跟的字符
		var cnInteger = '整';
		//整型完之后的单位
		var cnIntLast = '元';
		//最大处理的数字
		var maxNum = 999999999999999.9999;
		//金额整数部分
		var integerNum;
		//金额小数部分
		var decimalNum;
		//输出的中文金额字符串
		var chineseStr = '';
		//分离金额后用的数组,预约义
		var parts;
		if (money == '') { return ''; }
		money = parseFloat(money);
		if (money >= maxNum) {
		  //超出最大处理数字
		  return '';
		}
		if (money == 0) {
		  chineseStr = cnNums[0] + cnIntLast + cnInteger;
		  return chineseStr;
		}
		//转换为字符串
		money = money.toString();
		if (money.indexOf('.') == -1) {
		  integerNum = money;
		  decimalNum = '';
		} else {
		  parts = money.split('.');
		  integerNum = parts[0];
		  decimalNum = parts[1].substr(0, 4);
		}
		//获取整型部分转换
		if (parseInt(integerNum, 10) > 0) {
		  var zeroCount = 0;
		  var IntLen = integerNum.length;
		  for (var i = 0; i < IntLen; i++) {
			var n = integerNum.substr(i, 1);
			var p = IntLen - i - 1;
			var q = p / 4;
			var m = p % 4;
			if (n == '0') {
			  zeroCount++;
			} else {
			  if (zeroCount > 0) {
				chineseStr += cnNums[0];
			  }
			  //归零
			  zeroCount = 0;
			  chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
			}
			if (m == 0 && zeroCount < 4) {
			  chineseStr += cnIntUnits[q];
			}
		  }
		  chineseStr += cnIntLast;
		}
		//小数部分
		if (decimalNum != '') {
		  var decLen = decimalNum.length;
		  for (var i = 0; i < decLen; i++) {
			var n = decimalNum.substr(i, 1);
			if (n != '0') {
			  chineseStr += cnNums[Number(n)] + cnDecUnits[i];
			}
		  }
		}
		if (chineseStr == '') {
		  chineseStr += cnNums[0] + cnIntLast + cnInteger;
		} else if (decimalNum == '') {
		  chineseStr += cnInteger;
		}
		return chineseStr;
	}
复制代码

`

常规js运动动画函数

js动画是咱们前端开发最常接触的功能之一,虽然市面上有不少成熟的动画框架,可是有时候咱们只是一个小功能,没有必要引入那些库的时候,那么这个方法就足够你使用了: `

//js运动框架,四个参数,第一个要运动的元素,第二,要变化的值,注意此处是个json对象,第三个是要运动的速度,第四个是链式运动的函数
function cartoon(el, json, s, fn) {
	clearInterval(el.timer);	//开启定时器前线清除上个定时器
	el.timer = setInterval(function () {	//开启一个定时器
		var isStop = true;
		for (var attr in json) {	//循环参数里的json对象	
		var curStyle = null;	//声明一个空对象,用来存储当前元素的值
		if(attr == 'opacity'){	//若是参数是opacity,表示要改变透明度的变化
			curStyle = Math.round(parseFloat(getCss(el, attr))*100);	//parseFloat是保留小数,Math.round是四舍五入
			//之因此要用Math.round,就是考虑getCss取出来的数会有小数,因此让他四舍五入
		} else {
			curStyle = parseInt(getCss(el, attr));	//parseInt是取整
		}		 
		var speed = (json[attr] - curStyle) / s;	//计算速度
			speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);	//若是speed大于0就向上取整,小于0向下取整
			if (curStyle != json[attr]) {	//若是当前元素的值没有等于目标值
				isStop = false;		//把isStop设置为false
			}
			if (attr == 'opacity') {	//若是属性为opacity透明度,则单独设置属性
				el.style[attr] = (curStyle + speed) / 100;
				el.style.filter = 'alpha(opacity:'+(curStyle+speed)+')';
			} else {	//不是的采用原来设置的方式
				el.style[attr] = curStyle + speed + 'px';	
			}
			if (isStop) {	//只有isStop为true,才中止定时器
				clearInterval(el.timer);
				if (fn) fn();	//判断用户有没有传入链式函数
			}
		}	
	}, 30)
}

function getCss(el, attr) { // 这个是取元素样式的公共方法
	if (el.currentStyle) {
		return el.currentStyle[attr];
	} else {
		return getComputedStyle(el, null)[attr];
	}
}
复制代码

`

js图片压缩

图片压缩的功能,在移动端开发的应用上会较多,由于流量就是金钱,咱们要为用户省钱呀,最典型的图片压缩场景就是上传头像,你不可能自拍个10几MB的上传吧,那么试试这个方法吧:该方法是结合input标签的file类型使用的,接收两个参数,第一个是事件对象,第二个是个回调函数,回调函数的参数里能够拿到你须要的数据: `

function compressImg (event, callback) { // callback回调函数带一个对象参数
    // 选择的文件对象(file里只包含图片的体积,不包含图片的尺寸)
    var file = event.target.files[0];

    // 选择的文件是图片
    if(file.type.indexOf("image") === 0) {
        // 压缩图片须要的一些元素和对象
        var reader = new FileReader(),
            img = new Image();

        reader.readAsDataURL(file);
        // 文件base64化,以便获知图片原始尺寸
        reader.onload = function(e) {
            img.src = e.target.result;
        };
        // base64地址图片加载完毕后执行
        img.onload = function () {
            // 缩放图片须要的canvas(也能够在DOM中直接定义canvas标签,这样就能把压缩完的图片不转base64也能直接显示出来)
            var canvas = document.createElement('canvas');
            var context = canvas.getContext('2d');

            // 图片原始尺寸
            var originWidth = this.width;
            var originHeight = this.height;

            // 最大尺寸限制,可经过设置宽高来实现图片压缩程度
            var maxWidth = 1920,
                maxHeight = 1080;

            var targetWidth = originWidth,
                targetHeight = originHeight;
            if(originWidth > maxWidth || originHeight > maxHeight) {
                if(originWidth / originHeight > maxWidth / maxHeight) {
                    targetWidth = maxWidth;
                    targetHeight = Math.round(maxWidth * (originHeight / originWidth));
                } else {
                    targetHeight = maxHeight;
                    targetWidth = Math.round(maxHeight * (originWidth / originHeight));
                }
            }
            // canvas对图片进行缩放
            canvas.width = targetWidth;
            canvas.height = targetHeight;
            // 清除画布
            context.clearRect(0, 0, targetWidth, targetHeight);
            // 图片压缩
            context.drawImage(img, 0, 0, targetWidth, targetHeight);
            /*第一个参数是建立的img对象;第二三个参数是左上角坐标,后面两个是画布区域宽高*/

            //压缩后的图片转base64 url
            /*canvas.toDataURL(mimeType, qualityArgument),mimeType 默认值是'image/png';
             * qualityArgument表示导出的图片质量,只有导出为jpeg和webp格式的时候此参数才有效,默认值是0.92*/
            var newUrl = canvas.toDataURL('image/jpeg', 0.75);//base64 格式
            let obj = {imgSrc: newUrl}
            //也能够把压缩后的图片转blob格式用于上传
            canvas.toBlob((blob) => {
                obj.blob = blob;
                callback(obj);
            }, 'image/jpeg', 0.75)
        };
        } else {
            console.log('请选择你的图片')
        }
    }
    
    
    compressImg(event, function(data){  // 使用
        console.log(data)
    })
复制代码

`

检测浏览器类型

检测浏览器类型这个方法,主要在移动端作h5开发会用的较多,由于咱们并不知道用户用什么手机,用什么浏览,而咱们的代码逻辑也须要作相应的处理,此方法就是用来判断浏览器类型的,该方法能够返回个布尔值: `

var browser = {
			    versions:function(){
			    var u = window.navigator.userAgent; // 经过navigator.userAgent获取当前浏览器的信息
			    return {
			        trident: u.indexOf('Trident') > -1, //IE内核
			        presto: u.indexOf('Presto') > -1, //opera内核
			        webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
			        gecko: u.indexOf('Firefox') > -1, //火狐内核
			        mobile: !!u.match(/AppleWebKit.*Mobile.*/)||!!u.match(/AppleWebKit/), //是否为移动终端
			        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 || u.indexOf('Mac') > -1, //是否为iPhone或者安卓QQ浏览器
			        iPad: u.indexOf('iPad') > -1, //是否为iPad
			        webApp: u.indexOf('Safari') == -1 ,//是否为web应用程序,没有头部与底部
			        weixin: u.indexOf('MicroMessenger') == -1 //是否为微信浏览器
			        };
			    }()
			}
			
			console.log(browser.versions.trident)   // 检测是否为IE浏览器
			console.log(browser.versions.webKit)    // 检测是否为谷歌浏览器
复制代码

`

树数据递归处理函数

所谓树数据,其实我指的就是咱们平常开发中处理的那些树形结构,通常后台只会返回一个数组的数据,须要咱们处理他的数据层级结构,并显示在咱们的组件上去,例如element-ui的el-tree树组件: `

let data = [
			{id: 1, value: '动物'}, {id: 2, value: '植物'}, {id: 3, value: '微生物'}, {id: 4, value: '无机物'},
			{id: 5, parentId: 1, value: '脊椎类动物'}, {id: 6, parentId: 2, value: '木科植物'}, {id: 7, parentId: 1, value: '无脊椎类动物'}, {id: 8, parentId: 2, value: '草本植物'},
			{id: 9, parentId: 3, value: '细菌'}, {id: 10, parentId: 5, value: '老虎'}, {id: 11, parentId: 5, value: '狮子'}, {id: 12, parentId: 5, value: '猎豹'},
			{id: 13, parentId: 6, value: '松树'}, {id: 14, parentId: 6, value: '樟树'}, {id: 15, parentId: 6, value: '桦树'}, {id: 16, parentId: 7, value: '虾'},
			{id: 17, parentId: 7, value: '章鱼'}, {id: 18, parentId: 3, value: '真菌'}, {id: 19, parentId: 3, value: '病毒'}, {id: 20, parentId: 4, value: '黄金'},
			{id: 21, parentId: 8, value: '牡丹花'}, {id: 22, parentId: 8, value: '四叶草'}, {id: 23, parentId: 4, value: '白银'}, {id: 24, parentId: 4, value: '玉石'},
			{id: 25, parentId: 4, value: '珍珠'}, {id: 26, parentId: 9, value: '球状杆菌'}
		]
function classify (arr) {	// 树数据递归处理函数
			let first = [], others = [];
			arr.forEach(item => {
				item.children = [];
				if (!item.parentId) {
					first.push(item)
				} else {
					others.push(item)
				}
			});
			function recursion (arr, ary) {
				arr.forEach(item => {
					let other = []
					ary.map(cur => {
						if (item.id === cur.parentId) {
							item.children.push(cur)
						} else {
							other.push(cur)
						}
					})
					recursion(item.children, other);
				})
			}
			recursion(first, others);
			return first;
		}			
	let ary = classify(data);
复制代码

` 注意:该方法拿过去后,须要把你数据里的关键字段作个替换,由于通常的树数据都有当前数据的id和归属哪一个父数据下的一个parentId,我这里只是作的模拟,并不肯定你的数据也是这个字段名称,你须要找到你的关键字段替换就OK。

取限定范围内的随机数

该方法在咱们开发抽取随机幸运观众,随机礼品那种功能的时候应用较多,该方法接收两个参数,一个正整数类型的参数,一个取多少个随机数,会返回一个数组,数组里是随机的数字: `

function getRandom(integer, size) {
			let arr = [];
			function count() {
				if (arr.length < size) {
					let n = Math.round(Math.random() * integer);
					if(!arr.includes(n)) {
						arr.push(n)
					}
					count()
				}
			}
			count()
			return arr
		}
getRandom(100, 10)  // 随机取出0-100之内10位数字
复制代码

`

字符串加密方法

加密的功能通常来讲是先后端都须要作的,前端也会用啥md5加密之类的工具,此方法应用的场所只是针对咱们有些普通的数据,例如存储在localStorage这些数据,咱们不但愿他这么直白的显示在那,咱们就须要对他作个加密处理,这里包含两个方法,一个加密,一个解密,都须要一个字符串参数:

`

function compileStr (code) { // 对字符串进行加密 
				    var c = String.fromCharCode(code.charCodeAt(0) + code.length);  
				    for(var i = 1; i < code.length; i++){        
				        c += String.fromCharCode(code.charCodeAt(i) + code.charCodeAt(i - 1));  
				    }     
				    return escape(c);
  }
function uncompileStr (code) { // 字符串进行解密 
				    code = unescape(code);        
				    var c = String.fromCharCode(code.charCodeAt(0)-code.length);        
				    for(var i = 1; i < code.length; i++){        
				        c += String.fromCharCode(code.charCodeAt(i) - c.charCodeAt(i - 1));        
				    }        
				    return c;
			}
复制代码

` 注意:该方法的加密规则,你能够自行变化下,保证能够作到即使是拷贝同一份代码,大家的加解密的方式也不一样。

倒计时方法

倒计时是咱们前端开发较常见的功能需求之一了,例如商品列表的倒计时,啥啥活动倒计时,节日倒计时,本示例以节日倒计时为例演示,略微修改你就能够改为任何你想要的倒计时了,该方法接收一个参数,就是目标时间字符串: `

function countDown (targetDate) {	// 参数targetDate是目标时间
					var targetDateMs = Date.parse(targetDate); // 目标时间毫秒数
					var myDate = new Date()
					var curDateMs = Date.now();	// 获取当前时间毫秒数	方法1
					// var curDateMs = Date.parse(myDate)	// 获取当前时间的毫秒数 方法2
					
					if (curDateMs != targetDateMs) {	// 当前时间只要不等于目标时间毫秒数
						var timeDifference = targetDateMs-curDateMs;	// 当前时间与目标时间的时间差毫秒数
					
						var monthTotalMs = 1000 * 60 * 60 * 24 * 30;	// 月毫秒总数
						var dayTotalMs = 1000 * 60 * 60 * 24;	// 1天毫秒总数
						var hoursTotalMs = 1000 * 60 * 60;	 // 1小时毫秒总数
						var minutesTotalMs = 1000 * 60;	//	1分钟毫秒总数
						
						var month = Math.floor(timeDifference / monthTotalMs); //计算月
						var surplusDayMs = timeDifference - (month * monthTotalMs);	// 计算减去月后剩余的毫秒数
						var day = Math.floor(surplusDayMs / dayTotalMs);	// 计算天
						
						var surplusHoursMs = surplusDayMs - (day * dayTotalMs);	// 计算减去天后剩余的毫秒总数
						var hours = Math.floor(surplusHoursMs / hoursTotalMs);	// 计算小时
						var surplusMinutesMs = surplusHoursMs - (hours * hoursTotalMs); // 计算减去小时后还剩余的毫秒总数
						
						var minutes = Math.floor(surplusMinutesMs / minutesTotalMs);// 计算分
						var seconds = Math.ceil((surplusMinutesMs - (minutes * minutesTotalMs)) / 1000);	//剩余多少秒
						
						return `距离2019年倒计时:${month}月${day}天${toDou(hours)}时${toDou(minutes)}分${toDou(seconds)}秒`
					} else {	// 等于就中止计时器
						clearInterval(time);
					}
			    }
				
			function toDou(n){  // 用于补0的方法
			        if(n<10){
			            return '0'+n;
			        }else{
			            return ''+n;
			        }
				}
			    
			var time = setInterval(function(){
				document.querySelector('.div-date').innerText = countDown ('2020-01-01');
			}, 1000)
复制代码

`

小结

本章节的多数方法都是能够能够直接拿来使用的,个别方法须要根据你本身具体需求略微小改就OK了,固然这里的这些方法都是以我过往的业务需求写的,也许与你的需求有些差别,只要功能类似,我相信调整一下都是能够实现的,本章节后续会继续补充,各位大佬要是也有啥实用的公共小方法也能够共享一下,谢谢。

相关文章
相关标签/搜索