Today, I will share a JS utils tool function that has been accumulated and collected for a long time. The article has a lot of code. It is recommended to collect it and read it slowly. When you need it one day, open your long-lost favorites, I believe it will make you business code development with less effort.
It brings together time-related, DOM-related, URL-related, judgment-related, image-related, cache-related, etc. Part of the logic processing is relatively simple. If the business volume is relatively complex, it is recommended to use it carefully, but it should be more than enough for most projects. Next, let's go to the code part~
time dependent
Timestamp to custom format time
export const dateRegExp = (time, strText) => {
const date = new Date(time)
if (/(y+)/.test(strText)) {
strText = strText.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
}
const dataType = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
}
for (const typeKey in dataType) {
if (new RegExp(`(${typeKey})`).test(strText)) {
const typeValue = dataType[typeKey] + ''
strText = strText.replace(RegExp.$1, (RegExp.$1.length === 1 ? typeValue : padLeftZero(typeValue)))
}
}
return strText
}
format elapsed time from now
export function formatPassTime(startTime) {
var currentTime = Date.parse(new Date()),
time = currentTime - startTime,
day = parseInt(time / (1000 * 60 * 60 * 24)),
hour = parseInt(time / (1000 * 60 * 60)),
min = parseInt(time / (1000 * 60)),
month = parseInt(day / 30),
year = parseInt(month / 12);
if (year) return year + "年前"
if (month) return month + "个月前"
if (day) return day + "天前"
if (hour) return hour + "小时前"
if (min) return min + "分钟前"
else return '刚刚'
}
Determine if two dates in different formats are the same day
export function isSameDay(d1, d2) {
if (!d2) {
d2 = new Date();
}
var d1_year = d1.getFullYear(),
d1_month = d1.getMonth() + 1,
d1_date = d1.getDate();
var d2_year = d2.getFullYear(),
d2_month = d2.getMonth() + 1,
d2_date = d2.getDate()
return d1_date === d2_date && d1_month === d2_month && d1_year === d2_year;
}
Determine if the time is today
export function isTodayDate(time) {
if (new Date(time).toDateString() === new Date().toDateString()) {
return true;
}
return false;
}
URL related
URL parameter to object
export function parseQueryString(url) {
url = url ? url:window.location.search ;
let search = url[0] === '?' ? url : url.substring(url.lastIndexOf('?'));
let q = {};
search.replace(/([^?&=]+)=([^&]+)/g, (_, k, v) => q[k] = decodeURIComponent(v));
return q;
}
Get URL parameters
export function getQueryString(name) {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
const r = window.location.search.substr(1).match(reg)
if (r !== null) {
return decodeURI(r[2])
}
return null
}
Get the parameters behind the URL hash
export getHashQueryString = (key) => {
const after = window.location.href.split('?')[1]
if (after) {
const reg = new RegExp(`(^|&)${ key }=([^&]*)(&|$)`)
const r = after.match(reg)
if (r != null) {
return decodeURIComponent(r[2])
}
return null
}
return null
}
object serialization
export function serialize(query, encode = false) {
return Object.keys(query)
.map((key) => `${key}=${encode ? encodeURIComponent(query[key]) : query[key]}`)
.join('&')
}
Judgment related
Determine if Intersection is supported
export function isSupportIntersection() {
return (
'IntersectionObserver' in window &&
'IntersectionObserverEntry' in window &&
'intersectionRatio' in window.IntersectionObserverEntry.prototype
)
}
Determine if IOS
export const isIOS = (() => {
return /ios|iphone|ipad|ipod/.test(navigator.userAgent.toLowerCase())
})()
determine if android
export const isAndroid = (() {
return /android/.test(navigator.userAgent.toLowerCase())
})()
Judging WeChat's built-in browser
export function isWeixin() {
var ua = navigator.userAgent.toLowerCase();
return (ua.match(/MicroMessenger/i) == "micromessenger")
}
There are 2 ways to determine whether the webp format is supported
export function checkSupportWebp() {
return (
document
.createElement('canvas')
.toDataURL('image/webp')
.indexOf('data:image/webp') === 0
)
}
export function checkSupportWebp2() {
var img = new Image();
img.onload = img.onerror = (event) => {
return event && event.type === "load" ? img.width == 1 : false;
};
img.src = "data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA=";
}
Determine if the browser is mobile
export function isMobile() {
const agent = navigator.userAgent;
const k = ["android", "iphone", "ipod", "ipad", "windows phone", "mqqbrowser"];
let flag = false;
// Windows
if (agent.indexOf("Windows NT") < 0 || (agent.indexOf("Windows NT") >= 0 && agent.indexOf("compatible; MSIE 9.0;") >= 0)) {
// Mac PC
if (agent.indexOf("Windows NT") < 0 && agent.indexOf("Macintosh") < 0) {
for (let item of k) {
if (agent.indexOf(item) >= 0) {
flag = true;
break;
}
}
}
}
return flag;
}
file type determination
export function checkFileName(fileName, list) {
if (typeof fileName !== 'string') return;
let name = fileName.toLowerCase();
return list.some(i => name.endsWith(`.${i}`) === true)
}
export function isImage(fileName) {
return checkFileName(fileName, ['png', 'jpeg', 'jpg', 'png', 'bmp'])
}
export function isH5Video(fileName) {
return checkFileName(fileName, ['mp4', 'webm', 'ogg'])
}
export function isPdf(fileName) {
return checkFileName(fileName, ['pdf'])
}
export function isWord(fileName) {
return checkFileName(fileName, ['doc', 'docx'])
}
export function isExcel(fileName) {
return checkFileName(fileName, ['xlsx', 'xls'])
}
data type judgment
export function is(subject, type) {
return Object.prototype.toString.call(subject).substr(8, type.length).toLowerCase() === type
}
export function isArray(subject) {
return Array.isArray(subject)
}
export function isObject(subject) {
return is(subject, 'object')
}
...
export function isNum(subject) {
return !isNaN(subject) && is(subject, 'number')
}
DOM related
Query whether an element has a certain class
export function hasClass(el, className) {
let reg = new RegExp('(^|\\s)' + className + '(\\s|$)');
return reg.test(el.className);
}
add a class to an element
export function addClass(el, className) {
if (hasClass(el, className)) {
return;
}
let curClass = el.className.split(' ');
curClass.push(className);
el.className = curClass.join(' ');
}
remove the class of an element
export function removeClass(el, className) {
if (!hasClass(el, className)) {
return;
}
let reg = new RegExp('(^|\\s)' + className + '(\\s|$)', 'g');
el.className = el.className.replace(reg, ' ');
}
Get page scroll distance
export function getScrollTop() {
let e = 0
return (
document.documentElement && document.documentElement.scrollTop
? (e = document.documentElement.scrollTop)
: document.body && (e = document.body.scrollTop),
e
)
}
Scroll to a position callback
export function distanceScroll(distance, callback) {
const scrollTop = document.body.scrollTop || document.documentElement.scrollTop
const docHeight = document.body.clientHeight
const screenHeight = window.screen.availHeight
const differ = scrollTop > docHeight - screenHeight - distance
if (differ) {
callback && callback()
}
}
dial number
export const callPhone = (phone) => {
const aElement = document.createElement('a')
aElement.setAttribute('href', `tel:${phone}`)
document.body.appendChild(aElement)
aElement.click()
document.body.removeChild(aElement)
}
copy text
export function copy(value, callback) {
if (!document.queryCommandSupported('copy')) {
callback('暂不支持复制')
return
}
const textarea = document.createElement('textarea')
textarea.value = value
textarea.readOnly = Boolean('readOnly')
document.body.appendChild(textarea)
textarea.select()
textarea.setSelectionRange(0, value.length)
document.execCommand('copy')
textarea.remove()
callback('复制成功')
}
Dynamically load third-party js
export function asyncLoadScript(url) {
return new Promise(function (resolve, reject) {
const tag = document.getElementsByTagName('script')
for (const i of tag) {
if (i.src === url) {
resolve()
return
}
}
const script = document.createElement('script')
script.type = 'text/javascript'
script.src = url
script.onerror = reject
document.body.appendChild(script)
script.onload = () => {
resolve()
}
})
}
Solve the compatibility problem of requestAnimationFrame
export function requestAnimationFrame() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || function (callback) {
return setTimeout(callback, (callback.interval || (100 / 60) / 2);
};
}()
Dynamically create form form export data (POST)
const postExport = (url, data = {}) => {
const form = document.createElement("form");
form.style.display = "none";
form.action = `${Config.baseURL}${url}`;
form.method = "post";
document.body.appendChild(form);
// 动态创建input并给value赋值
for (const key in data) {
const input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = data[key];
form.appendChild(input);
}
form.submit();
form.remove();
}
Picture related
base64 to Buffer
export function dataURItoBuffer(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var buffer = new ArrayBuffer(byteString.length);
var view = new Uint8Array(buffer);
for (var i = 0; i < byteString.length; i++) {
view[i] = byteString.charCodeAt(i);
}
return buffer;
}
base64 to Blob
export function dataURItoBlob(dataURI) {
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var buffer = dataURItoBuffer(dataURI);
return new Blob([buffer], {
type: mimeString
});
}
Adjust the photo orientation
export function orientationHelper(canvas, ctx, orientation) {
var w = canvas.width;
var h = canvas.height;
if (orientation > 4) {
canvas.width = h;
canvas.height = w;
}
switch (orientation) {
case 2:
ctx.translate(w, 0);
ctx.scale(-1, 1);
break;
case 3:
ctx.translate(w, h);
ctx.rotate(Math.PI);
break;
case 4:
ctx.translate(0, h);
ctx.scale(1, -1);
break;
case 5:
ctx.rotate(0.5 * Math.PI);
ctx.scale(1, -1);
break;
case 6:
ctx.rotate(0.5 * Math.PI);
ctx.translate(0, -h);
break;
case 7:
ctx.rotate(0.5 * Math.PI);
ctx.translate(w, -h);
ctx.scale(-1, 1);
break;
case 8:
ctx.rotate(-0.5 * Math.PI);
ctx.translate(-w, 0);
break;
}
}
cache related
Get the specified cookie value
export const getCookie = (k) => {
const res = RegExp('(^|; )' + encodeURIComponent(k) + '=([^;]*)').exec(document.cookie)
return res && res[2]
}
Set cookie value
export function setCookie(name, value, expriesDays, encode = false) {
var Days = expriesDays || 10
var exp = new Date()
exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000)
const val = encode ? escape(value) : value
document.cookie = name + '=' + val + ';domain=zhuanzhuan.com;path=/;expires=' + exp.toUTCString()
}
Simple version of Storage operation, similar to sessionStorage and localStorage
const prefix = '_XXX_'
export function getStorage(key) {
const content = sessionStorage.getItem(`${prefix}${key}`)
if (content) {
try {
const params = JSON.parse(content)
const expires = params.expires
// 未设置过期 及 未过期
if (!expires || (expires && Date.now() <= expires)) {
return params.data
}
} catch (e) {
console.log(e)
}
}
}
export function setStorage(key, data = {}, expires) {
try {
const params = { data }
if (expires) {
params.expires = expires
}
sessionStorage.setItem(`${prefix}${key}`, JSON.stringify(params))
} catch (e) {
console.log(e)
}
}
digital correlation
Numbers are rounded to n decimal places
export function round(number, n) {
n = n ? parseInt(n) : 0
if (n <= 0) return Math.round(number)
number = Math.round(number * Math.pow(10, n)) / Math.pow(10, n)
return number
}
commas per thousand digits
export function toThousands(num) {
return num && num.toString()
.replace(/\d+/, function(s){
return s.replace(/(\d)(?=(\d{3})+$)/g, '$1,')
})
}
random number
export function random(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
String correlation
4 hidden asterisks in the middle of the mobile number
export function hideMobile(mobile) {
return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2")
}
Detect password strength 1: weak password 2: medium password 3: strong password 4: strong password
export function checkPassWord(str) {
let level = 0;
if (str.length < 6) {
return level
};
if (/[0-9]/.test(str)) {
level++
};
if (/[a-z]/.test(str)) {
level++
};
if (/[A-Z]/.test(str)) {
level++
};
if(/\W/.test(str)){
level++
}
return level
}
generate a random color
export function randomColor() {
return `rgb(${this.random(0, 255)}, ${this.random(0, 255)}, ${this.random(0, 255)})`
}
string replace all
export function replaceAll(s0, s1, s2){
return s0.replace(new RegExp(s1, "gm"), s2);
}
version number comparison
Enter two version numbers, the format is: 4.3.2, the return result is less than -1, equal to 0, greater than 1.
export function compareVersion(v1, v2) {
var s1 = v1.split(".").map(v => parseInt(v));
var s2 = v2.split(".").map(v => parseInt(v));
var len1 = s1.length, len2 = s2.length, commonLen = Math.min(len1, len2);
for (var i = 0; i < commonLen; ++i) {
if (seq1[i] != seq2[i])
return seq1[i]<seq2[i] ? -1 : 1;
}
return len1 === len2 ? 0 : (len1 < len2 ? -1 : 1);
}
Object to url string for export interface (GET) use
const objectToQueryString = (paramObj) => {
const tmpArray = []
// 特殊字符转义
const filter = (str) => {
str += '' // 隐式转换
str = str.replace(/%/g, '%25')
str = str.replace(/\+/g, '%2B')
str = str.replace(/ /g, '%20')
str = str.replace(/\//g, '%2F')
str = str.replace(/\?/g, '%3F')
str = str.replace(/&/g, '%26')
str = str.replace(/\=/g, '%3D')
str = str.replace(/#/g, '%23')
return str
}
for (const attr in paramObj) {
tmpArray.push(`${attr}=${filter(paramObj[attr])}`)
}
return tmpArray.join('&')
}
other
Function anti-shake
export function debounce(fn, delay) {
delay = delay || 1000;
let timer = null;
return function () {
let context = this;
let arg = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(context, arg);
}, delay);
};
}
Throttle function
export function throttle(fn, delay = 300) {
let timer = null;
return function () {
let context = this;
let args = arguments;
if (!timer) {
timer = setTimeout(function () {
fn.apply(context, args);
clearTimeout(timer);
}, delay);
}
};
}
At last
In addition to the scenarios shown in this article, there are also many situations that have not been listed. If you have a tool function that you think is very good, please leave a message to communicate~
Focus on front-end development, share dry goods related to front-end technology, public account: Nancheng Front-end (ID: nanchengfe)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。