這些JS工具函數(shù)夠你用到2020年底了
前言
活不多說,自己平時搜集的干貨函數(shù)奉上。
干貨函數(shù)
視頻全屏
// 全屏
function fullScreen(el) {
const isFullscreen =
document.fullScreen ||
document.mozFullScreen ||
document.webkitIsFullScreen;
if (!isFullscreen) {
//進(jìn)入全屏,多重短路表達(dá)式
(el.requestFullscreen && el.requestFullscreen()) ||
(el.mozRequestFullScreen && el.mozRequestFullScreen()) ||
(el.webkitRequestFullscreen && el.webkitRequestFullscreen()) ||
(el.msRequestFullscreen && el.msRequestFullscreen());
} else {
//退出全屏,三目運(yùn)算符
document.exitFullscreen
? document.exitFullscreen()
: document.mozCancelFullScreen
? document.mozCancelFullScreen()
: document.webkitExitFullscreen
? document.webkitExitFullscreen()
: "";
}
}
找出數(shù)字在數(shù)組中下一個相鄰的元素
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}-nsacrb5wa {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
}
數(shù)組去重
/**
* @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() {
// 據(jù)上一次觸發(fā)時間間隔
const last = +new Date() - timestamp
// 上次被包裝函數(shù)被調(diào)用時間間隔 last 小于設(shè)定時間間隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果設(shè)定為immediate===true,因?yàn)殚_始邊界已經(jīng)調(diào)用過了此處無需調(diào)用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function(...args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
// 如果延時不存在,重新設(shè)定延時
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); //將傳入的秒的值轉(zhuǎn)化為Number
let min = 0; // 初始化分
let h = 0; // 初始化小時
let result = "";
if (secondTime > 60) {
//如果秒數(shù)大于60,將秒數(shù)轉(zhuǎn)換成整數(shù)
min = parseInt(secondTime / 60); //獲取分鐘,除以60取整數(shù),得到整數(shù)分鐘
secondTime = parseInt(secondTime % 60); //獲取秒數(shù),秒數(shù)取佘,得到整數(shù)秒數(shù)
if (min > 60) {
//如果分鐘大于60,將分鐘轉(zhuǎn)換成小時
h = parseInt(min / 60); //獲取小時,獲取分鐘除以60,得到整數(shù)小時
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
帶有分割符的字符串轉(zhuǎn)化成一個n維數(shù)組
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;
// 如果當(dāng)前需要深拷貝的是一個對象的話
if (typeof target === 'object') {
// 如果是一個數(shù)組的話
if (Array.isArray(target)) {
result = []; // 將result賦值為一個數(shù)組,并且執(zhí)行遍歷
for (let i in target) {
// 遞歸克隆數(shù)組中的每一項(xiàng)
result.push(deepClone(target[i]))
}
// 判斷如果當(dāng)前的值是null的話;直接賦值為null
} else if(target===null) {
result = null;
// 判斷如果當(dāng)前的值是一個RegExp對象的話,直接賦值
} else if(target.constructor===RegExp){
result = target;
}else {
// 否則是普通對象,直接for in循環(huán),遞歸賦值對象的所有值
result = {};
for (let i in target) {
result[i] = deepClone(target[i]);
}
}
// 如果不是對象的話,就是基本數(shù)據(jù)類型,那么直接賦值
} else {
result = target;
}
// 返回最終結(jié)果
return result;
}
簡易版對象拷貝
function copy(obj) {
if(typeof obj == "object") { //判斷是否復(fù)雜類型
var result = obj.constructor == Array ? [] : {};//判斷數(shù)組類型或是object,數(shù)組即result=[],object即result={}
for(let i in obj) {
result[i] = typeof obj[i] == "object" ? copy(obj[i]) : obj[i]//判斷數(shù)據(jù)每一項(xiàng)是否是object
}
} else {
var result = obj //基本類型直接拷貝
}
return result;
}
實(shí)現(xiàn)一個模板引擎
function render(template, data) {
const reg = /\{\{(\w+)\}\}/; // 模板字符串正則
if (reg.test(template)) { // 判斷模板里是否有模板字符串
const name = reg.exec(template)[1]; // 查找當(dāng)前模板里第一個模板字符串的字段
template = template.replace(reg, data[name]); // 將第一個模板字符串渲染
return render(template, data); // 遞歸的渲染并返回渲染后的結(jié)構(gòu)
}
return template; // 如果模板沒有模板字符串直接返回
}
let template = '我是{{name}},年齡{{age}},性別{{sex}}';
let data = {
name: '姓名',
age: 18
}
render(template, data); // 我是姓名,年齡18,性別undefined
節(jié)流
// ①定時器實(shí)現(xiàn)
const throttle = (fn,delay = 500) =>{
let flag = true;
return (...args) => {
if(!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this,args);
flag = true;
},delay);
};
}
// ②時間戳實(shí)現(xiàn)
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函數(shù),用Promise做回調(diào)
* @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));
});
});
}
};
判斷瀏覽器環(huán)境
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;
}(),
};
定義數(shù)組內(nèi)部對象形式
const objArrtransArr = (olddata, oldval, oldname)=>{
const newArr = [];
olddata.forEach(item => {
// 定義數(shù)組內(nèi)部對象形式
let obj = {};
obj.value = item[oldval];
obj.name = item[oldname];
// 將對象數(shù)據(jù)推到數(shù)組中
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;
}
判斷瀏覽器是否支持?jǐn)z像頭
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);
});
}
回文算法
//忽略標(biāo)點(diǎn)符號、大小寫和空格,正著讀和反著讀一模一樣。
function made(str) {
var str1 = str.toLowerCase(); //先將字符串全部轉(zhuǎn)換為小寫
var reg = /[\W\_]/g; // 刪除所有非字母數(shù)字字符和下劃線
var str2 = str1.replace(reg, ""); // 去掉非字母和非數(shù)字
var str3 = str2.split(""); // 字符串分隔成數(shù)組
var str4 = str3.reverse(); // 反轉(zhuǎn)數(shù)組中的元素
var str5 = str4.join(""); // 反轉(zhuǎn)后的數(shù)組轉(zhuǎn)化為字符串
return str2 === str5;
}
持續(xù)更新…
結(jié)語
歡迎關(guān)注我的公眾號前端歷劫之路
回復(fù)關(guān)鍵詞電子書,即可獲取12本前端熱門電子書。
回復(fù)關(guān)鍵詞紅寶書第4版,即可獲取最新《JavaScript高級程序設(shè)計(jì)》(第四版)電子書。
關(guān)注公眾號后,點(diǎn)擊下方菜單即可加我微信,我拉攏了很多IT大佬,創(chuàng)建了一個技術(shù)交流、文章分享群,期待你的加入。
作者:Vam的金豆之路
主要領(lǐng)域:前端開發(fā)
我的微信:maomin9761
微信公眾號:前端歷劫之路