3
头图

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)


南城FE
2.2k 声望574 粉丝