干货函数
视频全屏
// 全屏 function fullScreen(el) { const isFullscreen = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen; if (!isFullscreen) { //进入全屏,多重短路表达式 (el.requestFullscreen && el.requestFullscreen()) || (el.mozRequestFullScreen && el.mozRequestFullScreen()) || (el.webkitRequestFullscreen && el.webkitRequestFullscreen()) || (el.msRequestFullscreen && el.msRequestFullscreen()); } else { //退出全屏,三目运算符 document.exitFullscreen ? document.exitFullscreen() : document.mozCancelFullScreen ? document.mozCancelFullScreen() : document.webkitExitFullscreen ? document.webkitExitFullscreen() : ""; } }
找出数字在数组中下一个相邻的元素
let i = ""; let rr = []; const name = (n, arr1)=>{ let num = Number(n); for (let i = 0; i < arr1.length; i++) { const element = arr1[i]; if (element != num) { rr.push(num--); } } return rr.find((el) => { let newel = String(el); return arr1.includes(newel); })} let arr = ["2", "4", "6", "8", "10", "12", "14", "16", "18", "20", "22", "24", "27", "30", "33", "36", "42", "48", "54", "60"] console.log(name('5',arr)); //4
格式化时间
/** * @param {number} time * @param {string} option * @returns {string} */ function formatTime(time, option) { if (('' + time).length === 10) { time = parseInt(time) * 1000 } else { time = +time } const d = new Date(time) const now = Date.now() const diff = (now - d) / 1000 if (diff < 30) { return '刚刚' } else if (diff < 3600) { // less 1 hour return Math.ceil(diff / 60) + '分钟前' } else if (diff < 3600 * 24) { return Math.ceil(diff / 3600) + '小时前' } else if (diff < 3600 * 24 * 2) { return '1天前' } if (option) { return parseTime(time, option) } else { return ( d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分' ) } }
解析时间
/** * Parse the time to string * @param {(Object|string|number)} time * @param {string} cFormat * @returns {string | null} */ function parseTime(time, cFormat) { if (arguments.length === 0 || !time) { return null } const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' let date if (typeof time === 'object') { date = time } else { if ((typeof time === 'string')) { if ((/^[0-9]+$/.test(time))) { // support "1548221490638" time = parseInt(time) } else { // support safari // https://stackoverflow.com/questions/4310953/invalid-date-in-safari time = time.replace(new RegExp(/-/gm), '/') } } if ((typeof time === 'number') && (time.toString().length === 10)) { time = time * 1000 } date = new Date(time) } const formatObj = { y: date.getFullYear(), m: date.getMonth() + 1, d: date.getDate(), h: date.getHours(), i: date.getMinutes(), s: date.getSeconds(), a: date.getDay() } const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => { const value = formatObj[key] // Note: getDay() returns 0 on Sunday if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] } return value.toString().padStart(2, '0') }) return time_str }
解析Url地址
/** * @param {string} url * @returns {Object} */ function param2Obj(url) { const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') if (!search) { return {} } const obj = {} const searchArr = search.split('&') searchArr.forEach(v => { const index = v.indexOf('=') if (index !== -1) { const name = v.substring(0, index) const val = v.substring(index + 1, v.length) obj[name] = val } }) return obj }
合并两个对象
/** * Merges two objects, giving the last one precedence * @param {Object} target * @param {(Object|Array)} source * @returns {Object} */ function objectMerge(target, source) { if (typeof target !== 'object') { target = {} } if (Array.isArray(source)) { return source.slice() } Object.keys(source).forEach(property => { const sourceProperty = source[property] if (typeof sourceProperty === 'object') { target[property] = objectMerge(target[property], sourceProperty) } else { target[property] = sourceProperty } }) return target }
数组去重
/** * @param {Array} arr * @returns {Array} */ function uniqueArr(arr) { return Array.from(new Set(arr)) }
防抖
/** * @param {Function} func * @param {number} wait * @param {boolean} immediate * @return {*} */ function debounce(func, wait, immediate) { let timeout, args, context, timestamp, result const later = function() { // 据上一次触发时间间隔 const last = +new Date() - timestamp // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait if (last < wait && last > 0) { timeout = setTimeout(later, wait - last) } else { timeout = null // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 if (!immediate) { result = func.apply(context, args) if (!timeout) context = args = null } } } return function(...args) { context = this timestamp = +new Date() const callNow = immediate && !timeout // 如果延时不存在,重新设定延时 if (!timeout) timeout = setTimeout(later, wait) if (callNow) { result = func.apply(context, args) context = args = null } return result } }
简易搜索
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input type="text" id="int"> </body> <script> let list = ["示例1","示例12","示例5","示例56"]; document.querySelector('#int').onchange=function(e){ console.log(search(e.target.value)); } function search(val) { if (val) { return list.filter(function (item) { return Object.keys(item).some(function (key) { return String(item[key]).toLowerCase().indexOf(val) > -1 }) }) } return list } </script> </html>
将秒化为时分秒
function formateSeconds (endTime) { let secondTime = parseInt(endTime); //将传入的秒的值转化为Number let min = 0; // 初始化分 let h = 0; // 初始化小时 let result = ""; if (secondTime > 60) { //如果秒数大于60,将秒数转换成整数 min = parseInt(secondTime / 60); //获取分钟,除以60取整数,得到整数分钟 secondTime = parseInt(secondTime % 60); //获取秒数,秒数取佘,得到整数秒数 if (min > 60) { //如果分钟大于60,将分钟转换成小时 h = parseInt(min / 60); //获取小时,获取分钟除以60,得到整数小时 min = parseInt(min % 60); //获取小时后取佘的分,获取分钟除以60取佘的分 } } result = `${h.toString().padStart(2, "0")}:${min.toString().padStart(2, "0")}:${secondTime.toString().padStart(2, "0")}`; return result; }
将时分秒化为秒
function formSeconds (times) { let arr = times.split(":"); let s = arr[2]; let m = arr[1]; let h = arr[0]; let m1 = m<10?m.replace(/\b(0+)/gi,""):m; let h1 = h<10?h.replace(/\b(0+)/gi,""):h; return m1*60+Number(h1)+Number(s) }
对象深层遍历
var obj = { a:{ b:{ c:"maomin" } } } const safeGet = (obj, path) => { try { return path.split('.').reduce((o, k) => o[k], obj) } catch (e) { return undefined } } console.log(safeGet(obj,'a.b.c'));// maomin
带有分割符的字符串转化成一个n维数组
var str = "A-2-12"; var str1 = str.split('-'); var arr = str1.reverse().reduce((pre,cur,i) => { if(i==0) { pre.push(cur) return pre } return [cur,pre] },[]) console.log(arr) // ["A"["B",["C"]]]
获取时间戳
function thedata(d){ return d.replace(/\-/g, "\/") } var serverTime = parseInt(new Date(thedata('2020-08-12 15:52:11')).valueOf()); console.log(serverTime); // 1597218731000,获取到时间戳
对象深拷贝
function deepClone(target) { // 定义一个变量 let result; // 如果当前需要深拷贝的是一个对象的话 if (typeof target === 'object') { // 如果是一个数组的话 if (Array.isArray(target)) { result = []; // 将result赋值为一个数组,并且执行遍历 for (let i in target) { // 递归克隆数组中的每一项 result.push(deepClone(target[i])) } // 判断如果当前的值是null的话;直接赋值为null } else if(target===null) { result = null; // 判断如果当前的值是一个RegExp对象的话,直接赋值 } else if(target.constructor===RegExp){ result = target; }else { // 否则是普通对象,直接for in循环,递归赋值对象的所有值 result = {}; for (let i in target) { result[i] = deepClone(target[i]); } } // 如果不是对象的话,就是基本数据类型,那么直接赋值 } else { result = target; } // 返回最终结果 return result; }
简易版对象拷贝
function copy(obj) { if(typeof obj == "object") { //判断是否复杂类型 var result = obj.constructor == Array ? [] : {};//判断数组类型或是object,数组即result=[],object即result={} for(let i in obj) { result[i] = typeof obj[i] == "object" ? copy(obj[i]) : obj[i]//判断数据每一项是否是object } } else { var result = obj //基本类型直接拷贝 } return result; }
实现一个模板引擎
function render(template, data) { const reg = /\{\{(\w+)\}\}/; // 模板字符串正则 if (reg.test(template)) { // 判断模板里是否有模板字符串 const name = reg.exec(template)[1]; // 查找当前模板里第一个模板字符串的字段 template = template.replace(reg, data[name]); // 将第一个模板字符串渲染 return render(template, data); // 递归的渲染并返回渲染后的结构 } return template; // 如果模板没有模板字符串直接返回 } let template = '我是{{name}},年龄{{age}},性别{{sex}}'; let data = { name: '姓名', age: 18 } render(template, data); // 我是姓名,年龄18,性别undefined
节流
// ①定时器实现 const throttle = (fn,delay = 500) =>{ let flag = true; return (...args) => { if(!flag) return; flag = false; setTimeout(() => { fn.apply(this,args); flag = true; },delay); }; } // ②时间戳实现 const throttle = (fn,delay = 500) => { let preTime = Date.now(); return (...args) => { const nowTime = Date.now(); if(nowTime - preTime >= delay){ preTime = Date.now(); fn.apply(this,args); } } }
封装fetch
/** * 封装fetch函数,用Promise做回调 * @type {{get: (function(*=)), post: (function(*=, *=))}} */ const fetchUtil = { get: (url) => { return new Promise((resolve, reject) => { fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/x-www-form-urlencoded', } }).then((response) => response.json()).then(response => { resolve(response); }).catch(err => { reject(new Error(err)); }); }); }, post: (url, params) => { return new Promise((resolve, reject) => { fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: params }).then((response) => response.json()).then(response => { resolve(response); }).catch(err => { reject(new Error(err)); }); }); } };
判断浏览器环境
function getSystem(){ const mac = /mac/i, linux = /linux/i, win = /win/i; const platform = navigator.platform.toLowerCase(); if(mac.test(platform)){ return 'MAC'; } else if(win.test(platform)){ return 'WIN'; } else if(linux.test(platform)){ return 'Linux'; } return undefined; } const browser = { versions:function(){ let ret = 'xxSys'; const u = navigator.userAgent; const isMobile = !!u.match(/AppleWebKit.*Mobile.*/), ios = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), android = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; if(isMobile){ if(ios) return 'IOS'; if(android) return 'Android'; } else { ret = getSystem() || ret; } return ret; }(), };
定义数组内部对象形式
const objArrtransArr = (olddata, oldval, oldname)=>{ const newArr = []; olddata.forEach(item => { // 定义数组内部对象形式 let obj = {}; obj.value = item[oldval]; obj.name = item[oldname]; // 将对象数据推到数组中 newArr.push(obj); }); return newArr; }
解析html字符串
function (htmlobj) { var el = document.createElement('div'); el.innerHTML = htmlobj; var tags = el.getElementsByTagName('img'); var text = tags[0].getAttribute("src"); return text; }
判断浏览器是否支持摄像头
function videoCheck () { var deviceList = []; navigator.mediaDevices .enumerateDevices() .then(devices => { devices.forEach(device => { deviceList.push(device.kind); }); if (deviceList.indexOf("videoinput") == "-1") { console.info("没有摄像头"); return false; } else { console.info("有摄像头"); } }) .catch(function(err) { alert(err.name + ": " + err.message); }); }
回文算法
//忽略标点符号、大小写和空格,正着读和反着读一模一样。 function made(str) { var str1 = str.toLowerCase(); //先将字符串全部转换为小写 var reg = /[\W\_]/g; // 删除所有非字母数字字符和下划线 var str2 = str1.replace(reg, ""); // 去掉非字母和非数字 var str3 = str2.split(""); // 字符串分隔成数组 var str4 = str3.reverse(); // 反转数组中的元素 var str5 = str4.join(""); // 反转后的数组转化为字符串 return str2 === str5; }
持续更新...