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了,固然這裏的這些方法都是以我過往的業務需求寫的,也許與你的需求有些差別,只要功能類似,我相信調整一下都是能夠實現的,本章節後續會繼續補充,各位大佬要是也有啥實用的公共小方法也能夠共享一下,謝謝。

相關文章
相關標籤/搜索