一些常用的工具函式
阿新 • • 發佈:2020-12-07
1. 下載檔案到本地
1 function downLoadFile(data,fileName){ 2 if (!data) { 3 return 4 } 5 var blob = new Blob([data]); // <!document><head><meta charset="utf-8"></head><body><h1>測試</h1></body> 6 if (window.navigator && window.navigator.msSaveOrOpenBlob) { //View Codefor IE 7 window.navigator.msSaveOrOpenBlob(blob,fileName); 8 }else{ 9 let url = window.URL.createObjectURL(blob); 10 let link = document.createElement('a'); 11 link.style.display = 'none'; 12 link.href = url; 13 link.setAttribute('download', fileName);14 15 document.body.appendChild(link); 16 link.click(); 17 } 18 }
2. 複製內容到剪貼簿:
// 複製內容到剪貼簿 function copyToClip(text, callback) { if(document.execCommand('Copy')){ //建立input var inputZ = document.createElement('input'); //新增Id,用於後續操作 inputZ.setAttribute('id','inputCopy');View Code//獲取當前連結 inputZ.value = text; //建立的input新增到body document.body.appendChild(inputZ); //選中input中的值 document.getElementById('inputCopy').select(); //把值複製下來 document.execCommand('Copy') //刪除新增的input document.body.removeChild(inputZ); // 成功回撥1 typeof callback === 'function' && callback(1); }else{ // 失敗回撥2 typeof callback === 'function' && callback(2); } }
3. 全屏和退出全屏
// 全屏 function fullscreen(elem) { var docElm = elem || document.documentElement; if (docElm.requestFullscreen) { docElm.requestFullscreen(); } else if (docElm.mozRequestFullScreen) { docElm.mozRequestFullScreen(); } else if (docElm.webkitRequestFullScreen) { docElm.webkitRequestFullScreen(); } else if (docElm.msRequestFullscreen) { docElm.msRequestFullscreen(); } } // 退出全屏 function exitFullscreen() { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitCancelFullScreen) { document.webkitCancelFullScreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } }View Code
4. 獲取裝置資訊
// from: vue.js function getPlatForm () { var inBrowser = typeof window !== 'undefined'; var inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform; var weexPlatform = inWeex && WXEnvironment.platform.toLowerCase(); var UA = inBrowser && window.navigator.userAgent.toLowerCase(); var isIE = UA && /msie|trident/.test(UA); var isIE9 = UA && UA.indexOf('msie 9.0') > 0; var isEdge = UA && UA.indexOf('edge/') > 0; var isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android'); var isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios'); var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge; var isPhantomJS = UA && /phantomjs/.test(UA); var isFF = UA && UA.match(/firefox\/(\d+)/); return { inBrowser, inWeex, weexPlatform, UA, isIE, isIE9, isEdge, isAndroid, isIOS, isChrome, isPhantomJS, isFF } }View Code
5. 日期格式化
function dateFormat(data, fmt) { !fmt && (fmt = 'yyyy/MM/dd hh:mm:ss') if (typeof data === 'number') { data = data.toString().substr(0, 13) } if (typeof data === 'string') { data = new Date(parseInt(data)) } let o = { 'M+': data.getMonth() + 1, // 月份 'd+': data.getDate(), // 日 'h+': data.getHours(), // 小時 'm+': data.getMinutes(), // 分 's+': data.getSeconds(), // 秒 'q+': Math.floor((data.getMonth() + 3) / 3), // 季度 S: data.getMilliseconds() // 毫秒 } if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (data.getFullYear() + '').substr(4 - RegExp.$1.length)) } for (let k in o) { if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace( RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length) ) } } return fmt }View Code
6. 字串格式化(模板)
function compile(template){ var evalExpr = /<%=(.+?)%>/g; var expr = /<%([\s\S]+?)%>/g; template = template .replace(evalExpr, '`); \n echo( $1 );\n echo(`') .replace(expr, '`);\n $1 \n echo(`'); template = 'echo(`' + template + '`);'; var script = '\n' + 'var output = "";\n' + 'function echo(html){ \n' + 'output += html; \n' + '};\n' + template + '\n' + 'return output; \n'; return new Function('data', script); }View Code
7. 獲取周/根據周獲取日期範圍
// 獲取周: 一個月最多可以跨 6周, 31天, 首尾恰好位於起始時間 // from: https://stackoverflow.com/questions/9045868/javascript-date-getweek function getWeek(timeStr) { var _this = new Date(timeStr); // We have to compare against the first monday of the year not the 01/01 // 60*60*24*1000 = 86400000 // 'onejan_next_monday_time' reffers to the miliseconds of the next monday after 01/01 var day_miliseconds = 86400000, onejan = new Date(_this.getFullYear(), 0, 1, 0, 0, 0), onejan_day = (onejan.getDay() == 0) ? 7 : onejan.getDay(), days_for_next_monday = (8 - onejan_day), onejan_next_monday_time = onejan.getTime() + (days_for_next_monday * day_miliseconds), // If one jan is not a monday, get the first monday of the year first_monday_year_time = (onejan_day > 1) ? onejan_next_monday_time : onejan.getTime(), this_date = new Date(_this.getFullYear(), _this.getMonth(), _this.getDate(), 0, 0, 0), // This at 00:00:00 this_time = this_date.getTime(), days_from_first_monday = Math.round(((this_time - first_monday_year_time) / day_miliseconds)); var first_monday_year = new Date(first_monday_year_time); // We add 1 to "days_from_first_monday" because if "days_from_first_monday" is *7, // then 7/7 = 1, and as we are 7 days from first monday, // we should be in week number 2 instead of week number 1 (7/7=1) // We consider week number as 52 when "days_from_first_monday" is lower than 0, // that means the actual week started before the first monday so that means we are on the firsts // days of the year (ex: we are on Friday 01/01, then "days_from_first_monday"=-3, // so friday 01/01 is part of week number 52 from past year) // "days_from_first_monday<=364" because (364+1)/7 == 52, if we are on day 365, then (365+1)/7 >= 52 (Math.ceil(366/7)=53) and thats wrong return (days_from_first_monday >= 0 && days_from_first_monday < 364) ? Math.ceil((days_from_first_monday + 1) / 7) : 52; } // 對 week 的一步反運算, 計算情況: 2019,3: 2019年第3周, 對應是哪天到哪天; function getWeekRange(year, week, tpl) { var day_miliseconds = 86400000, onejan = new Date(year, 0, 1, 0, 0, 0), onejan_day = (onejan.getDay() == 0) ? 7 : onejan.getDay(), days_for_next_monday = (8 - onejan_day), onejan_next_monday_time = onejan.getTime() + (days_for_next_monday * day_miliseconds), first_monday_year_time = (onejan_day > 1) ? onejan_next_monday_time : onejan.getTime(), target_week_monday_time = first_monday_year_time + day_miliseconds * 7 * (week - 1), target_week_sunday_time = target_week_monday_time + day_miliseconds * 6 - 1000; return [formatDate(target_week_monday_time, tpl || 'yyyy-MM-dd'), formatDate(target_week_sunday_time, tpl || 'yyyy-MM-dd')] }View Code
8. 深拷貝
// 深拷貝 function deepCopy(obj) { var copy; // Handle the 3 simple types, and null or undefined if (null == obj || "object" != typeof obj) return obj; // Handle Date if (obj instanceof Date) { copy = new Date(); copy.setTime(obj.getTime()); return copy; } // Handle Array if (obj instanceof Array) { copy = []; for (var i = 0, len = obj.length; i < len; i++) { copy[i] = deepCopy(obj[i]); } return copy; } // Handle Object if (obj instanceof Object) { copy = {}; for (var attr in obj) { if (obj.hasOwnProperty(attr)) copy[attr] = deepCopy(obj[attr]); } return copy; } if (isPrimitiveValue(obj)) { copy = obj; return copy; } throw new Error("Unable to copy obj! Its type isn't supported."); }View Code
9. 是否相同物件
function deepEqual(x, y) { var core_toString = Object.prototype.toString var ta = core_toString.call(x) var tb = core_toString.call(y) if (x === y) { return true } if (ta !== tb) { return false } if (!(typeof x == 'object' && x != null) || !(typeof y == 'object' && y != null)) { return false } if (Object.keys(x).length != Object.keys(y).length) { return false } for (var prop in x) { if (y.hasOwnProperty(prop)) { if (!deepEqual(x[prop], y[prop])) { return false } } else { return false } } return ta === '[object Date]' ? x.valueOf() == y.valueOf() : true }View Code
10. 找出兩個物件的差異欄位
function diff(lobj, robj, change, path, key) { var ltype = type(lobj), rtype = type(robj); var ldefined = ltype !== 'undefined' var rdefined = rtype !== 'undefined' path = path || [] var currentPath = path.slice(0) if (typeof key !== 'undefined' && key !== null) { currentPath.push(key) } if (!ldefined && rdefined) { change.push({ type: 'add', path: currentPath, rhs: robj }) } else if (ldefined && !rdefined) { change.push({ type: 'delete', path: currentPath, lhs: lobj }) } else if (ltype !== rtype) { change.push({ type: 'edit', path: currentPath, lhs: lobj, rhs:robj }) } else { if (isPrimaty(lobj)) { if (lobj !== robj) { change.push({ type: 'edit', path: currentPath, lhs: lobj, rhs: robj }) } } else if (ltype === 'object') { var aKeys = Object.keys(lobj) var pKeys = Object.keys(robj) var ckeys = unique(aKeys.concat(pKeys)) var p; for (var i=0; i<ckeys.length; i++) { diff(lobj[ckeys[i]], robj[ckeys[i]], change, currentPath, ckeys[i]) } } else if (ltype === 'array') { var maxLen = Math.max.apply(null, [lobj.length, robj.length]); for(var i=0; i<maxLen; i++) { diff(lobj[i], robj[i], change, currentPath, i) } // Date, ExpExc 等 } else if (ltype === 'date'){ if (lobj.valueOf() !== robj.valueOf()) { change.push({ type: 'edit', path: currentPath, lhs: lobj, rhs: robj }) } } } } 輔助方法: // 簡單實現 function unique (arr) { var res = []; for(var i = 0; i < arr.length; i++) { if (res.indexOf(arr[i]) === -1) { res.push(arr[i]) } } return res } function isPrimaty (value) { return ( typeof value === 'number' || typeof value === 'string' || typeof value === 'boolean' || typeof value === 'undefined' || typeof value === 'symbol' || typeof value === 'bigint' || (typeof value === 'object' && value === null) ) } function type(input) { return ({}).toString.call(input).slice(8, -1).toLowerCase(); } 示例: var obj1 = { a: 123, b: { b1: 12, b2: 22, b3: '123' }, c: [1, 4], d: { c1: 4 }, e: null, f: new Date() } var obj2 = { a: 123, b: { b1: 12, b2: 33 }, c: [4, 1], d: { c1: 4 }, f: new Date('2020-12-30') } var res = [] diff(obj1, obj2, res); res => [ { "type":"edit", "path":["b","b2"], "lhs":22, "rhs":33 },{ "type":"delete", "path":["b","b3"], "lhs":"123" },{ "type":"delete", "path":["e"], "lhs":null },{ "type":"edit", "path":["f"], "lhs":"2020-07-02T08:28:00.640Z", "rhs":"2020-12-30T00:00:00.000Z" } ]View Code