", js-common-functions index.ts

Source

index.ts

/** 
 *@function 
 * @name:Deep copy
 * @param {Object} obj Objects to copy
 * @returns {Object} Deep copy of the object
 */
export function deepClone(values: any): any {
  var copy;

  // Handle the 3 simple types, and null or undefined
  if (null == values || "object" != typeof values) return values;

  // Handle Date
  if (values instanceof Date) {
    copy = new Date();
    copy.setTime(values.getTime());
    return copy;
  }

  // Handle Array
  if (values instanceof Array) {
    copy = [];
    for (var i = 0, len = values.length; i < len; i++) {
      copy[i] = deepClone(values[i]);
    }
    return copy;
  }

  // Handle Object
  if (values instanceof Object) {
    copy = {} as any;
    for (var attr in values) {
      if (values.hasOwnProperty(attr)) copy[attr] = deepClone(values[attr]);
    }
    return copy;
  }

  throw new Error("Unable to copy values! Its type isn't supported.");
}

/**
* @name: Shallow copy
* @param {Object} obj Objects to copy
* @returns {Object} Shallow copy of the object
*/
export function shallowClone<T>(obj: T): T {
  let result: any;
  if (typeof obj === 'object') {
    if (Array.isArray(obj)) {
      result = [];
      for (let i = 0; i < obj.length; i++) {
        result.push(obj[i]);
      }
    } else {
      result = {};
      for (let key in obj) {
        result[key] = obj[key];
      }
    }
  } else {
    result = obj;
  }
  return result;
}

/** 
* @name:Get the number of object attributes
* @param {Object} obj To get an object of the number of properties
*/
export function getObjectLength(obj: object): number {
  let count = 0;
  for (let i = 0; i < Object.keys(obj).length; i++) {
    count++;
  }
  return count;
}

/**
* @name: Time format X days ago
* @param {*} time Timestamp
* @return {*} Time format X days ago
* @example
* console.log(timeFormat(1588888888)); // 2 days ago
*/
export function timeFormat(time: any): any {
  let result;
  let minute = 1000 * 60;
  let hour = minute * 60;
  let day = hour * 24;
  let month = day * 30;
  let now = new Date().getTime();
  let diffValue = now - time;
  if (diffValue < 0) {
    //console.log("结束日期不能小于开始日期!");
  }
  let monthC: any = diffValue / month;
  let weekC: any = diffValue / (7 * day);
  let dayC: any = diffValue / day;
  let hourC: any = diffValue / hour;
  let minC: any = diffValue / minute;
  if (monthC >= 1) {
    result = "发表于" + parseInt(monthC) + "个月前";
  } else if (weekC >= 1) {
    result = "发表于" + parseInt(weekC) + "周前";
  } else if (dayC >= 1) {
    result = "发表于" + parseInt(dayC) + "天前";
  } else if (hourC >= 1) {
    result = "发表于" + parseInt(hourC) + "个小时前";
  } else if (minC >= 1) {
    result = "发表于" + parseInt(minC) + "分钟前";
  } else result = "刚刚发表";
  return result;
}


/**
* @name: Package Ajax Promise
* @param {String} url Request address 
* @param {Object} data Request parameters 
* @param {String} method Request way get/post
* @returns {Promise}
*/
export function ajax({ url, data, method = "GET" }: { url: string, data: any, method: string }): Promise<any> {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest()
    xhr.open(method, url, true)
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
          resolve(xhr.responseText)
        } else {
          reject(xhr.status)
        }
      }
    }
    if (method === "GET") {
      xhr.send()
    } else {
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
      xhr.send(data)
    }
  })
}

/**
* @name: Judging whether the array contains a value
* @param {Array} arr Array to be judged
* @param {any} value To determine the value
*/
export function isContain(arr: any[], value: any) {
  return arr.includes(value)
}

/** 
* @name: Array to heavy
* @param {Array} arr Array to be heavy
* @returns {Array} 
* @example
* console.log(unique([1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10])) // [1,2,3,4,5,6,7,8,9,10]
*/
export function unique(arr: any[]) {
  let result: any[] = [];
  for (let i = 0; i < arr.length; i++) {
    if (!result.includes(arr[i])) {
      result.push(arr[i]);
    }
  }
  return result;
}

/**
* @name: Generate random colors
* @return {String} Random color
* @example
* console.log(randomColor()) // #e6e6e6
*/
export function randomColor() {
  return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);
}

/**
* @name: Array sort
* @param {Array} arr Array to be sorted
* @param {String} key Sort KEY
* @param {String} order Sort mode, ASC ascending, DESC descending
* @example
* sortBy([{name: 'a'}, {name: 'b'}], 'name', 'asc')
* // => [{name: 'a'}, {name: 'b'}]
* sortBy([{name: 'a'}, {name: 'b'}], 'name', 'desc')
* // => [{name: 'b'}, {name: 'a'}]
* sortBy([{name: 'a'}, {name: 'b'}], 'name')
* // => [{name: 'a'}, {name: 'b'}]
*/
export function sortBy(arr: any[], key: string, order: string = 'asc') {
  return arr.sort((a, b) => {
    if (a[key] > b[key]) {
      return order === 'asc' ? 1 : -1;
    } else if (a[key] < b[key]) {
      return order === 'asc' ? -1 : 1;
    } else {
      return 0;
    }
  })
}

/**
* @name: Random verification code
* @param {Number} len Verification code length
*/
export function randomCode(len: number) {
  let str = '';
  for (let i = 0; i < len; i++) {
    str += Math.floor(Math.random() * 10);
  }
  return str;
}

/**
* @name: Password verification regular
* @param {String} password password
* @returns {Boolean}
*/
export function checkPassword(password: string) {
  let reg = /^[a-zA-Z0-9]{6,20}$/;
  return reg.test(password);
}

/**
* @name: Regular verification mailbox
* @param {String} email Mail
* @returns {Boolean}
*/
export function checkEmail(email: string) {
  let reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/;
  return reg.test(email);
}

/**
* @name: Regular verification mobile phone number
* @param {String} phone phone number
* @param {Boolean} isChina Is it a Chinese mobile phone number?
* @returns {Boolean}
*/
export function checkPhone(phone: string, isChina: boolean = true) {
  let reg = isChina ? /^1[3-9]\d{9}$/ : /^[0-9]{8,15}$/;
  return reg.test(phone);
}

/**
* @name: Regular verification ID card number
* @param {String} idCard ID number
* @returns {Boolean}
*/
export function checkIdCard(idCard: string) {
  let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
  return reg.test(idCard);
}

/**
* @name: Regular verification bank card number
* @param {String} bankCard Bank card number
* @returns {Boolean} 
*/
export function checkBankCard(bankCard: string) {
  let reg = /^(\d{16}|\d{19})$/;
  return reg.test(bankCard);
}

/**
* @name:Judging the mobile phone system
*/
export function checkPhoneSystem() {
  let u = navigator.userAgent;
  let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //Android terminal
  let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //iOS terminal
  return { isAndroid, isiOS };
}

/**
* @name: Judging the mobile phone number home
* @param {String} phone phone number
*/
export function getPhoneAttribution(phone: string) {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', `https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=${phone}`);
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4 && xhr.status === 200) {
        let data = JSON.parse(xhr.responseText);
        if (data.province) {
          resolve(data.province);
        } else {
          reject(new Error('Mobile phone number error'));
        }
      } else {
        reject(new Error('Request failed'));
      }
    }
    xhr.send();
  })
}

interface setting {
  method?: string, // Request way
  body?: any, // Request body
  headers?: any, // Request head
  mode?: string, // Request mode
  credentials?: any, // Request credential
  cache?: string, // Request cache
  redirect?: string, // Request redirection
  dataType?: string, // Return data type
  data?: any, // Request parameters
}

/**
* @name: Package FETCH request
* @param {string} url Request address
* @param {string} setting Request configuration
* @return {Promise} Request promise
*/
export function fetch(url: string, setting: setting) { // FETCH request package
  let opts = { // Set the initial value of the parameter
    method: (setting.method || 'GET').toUpperCase(), // Request way
    headers: setting.headers || {}, // Request head setting
    credentials: setting.credentials || true, // Set whether cookies send together
    body: setting.body || {},
    mode: setting.mode || 'no-cors', // Can set cors, no-cors, same-origin
    redirect: setting.redirect || 'follow', // follow, error, manual
    cache: setting.cache || 'default' // Set cache mode(default, reload, no-cache)
  }
  let dataType = setting.dataType || 'json' // Parsing
  let data = setting.data || '' // parameter
  let paramsFormat = function (obj: any) { // Parameter format
    var str = ''
    for (var i in obj) {
      str += `${i}=${obj[i]}&`
    }
    return str.split('').slice(0, -1).join('')
  }

  if (opts.method === 'GET') {
    url = url + (data ? `?${paramsFormat(data)}` : '')
  } else {
    setting.body = data || {}
  }
  return new Promise((resolve, reject) => {
    fetch(url, opts).then(async (res: any) => {
      let data = dataType === 'text' ? await res.text() : dataType === 'blob' ? await res.blob() : await res.json()
      resolve(data)
    }).catch(e => {
      reject(e)
    })
  })
}

/**
 * @name: Determine if it is a PC
 * @return {Boolean} true or false
 */
export function isPC() { // Is it a PC side?
  let userAgentInfo = navigator.userAgent
  let Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
  let flag = true
  for (let v = 0; v < Agents.length; v++) {
    if (userAgentInfo.indexOf(Agents[v]) > 0) {
      flag = false
      break
    }
  }
  return flag
}

/**
* @name: Remove string spaces
* @param {string} str String
* @param {string} type Type 1: All space type 2: front and rear space type 3: Front space type 4: rear
* @returns {string} String
*/
export function trim(str: string, type: number) {
  type = type || 1
  switch (type) {
    case 1:
      return str.replace(/\s+/g, '')
    case 2:
      return str.replace(/(^\s*)|(\s*$)/g, '')
    case 3:
      return str.replace(/(^\s*)/g, '')
    case 4:
      return str.replace(/(\s*$)/g, '')
    default:
      return str
  }
}

/**
* @name: Filter HTML code
* @param {string} str String
* @return {string} String
*/
export function filterHTML(str: string) {
  return str.replace(/<\/?[^>]*>/g, '').replace(/[ | ]*\n/g, '\n').replace(/\n[\s| | ]*\r/g, '\n').replace(/&nbsp;/ig, '')
}

/**
* @name: Judging whether it is a floating point number 
* @param {any} val 
* @return {boolean} 
*/
export function isFloat(val: any) {
  return /^\d+\.\d+$/.test(val)
}

/**
 * @name: Judgment is an integer
 * @param {any} val 
 * @return {boolean}
 */
export function isInteger(val: any) {
  return /^\d+$/.test(val)
}

/**
* @name: Object serialization
* @param  {Object} obj 
* @return {String}
*/
export function stringifyQueryString(obj: any): string {
  if (!obj) return '';
  var pairs = [];

  for (var key in obj) {
    var value = obj[key];

    if (value instanceof Array) {
      for (var i = 0; i < value.length; ++i) {
        pairs.push(encodeURIComponent(key + '[' + i + ']') + '=' + encodeURIComponent(value[i]));
      }
      continue;
    }

    pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
  }

  return pairs.join('&');
}

/**
 * @desc Get the distance from the top of the scroll bar
 * @return {Number} The distance from the top of the scroll bar
 */
export function getScrollTop(): number {
  return (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
}

/**
 * 
 * @desc H5 soft keyboard is retracted, bounce back
 * When the software keyboard pops up will change the current Window.innerHeight, monitor this value change
 * @param {Function} downCb When the soft keyboard bounces, the retracted callback
 * @param {Function} upCb When the soft keyboard bounces
 * @return {Function} 
 */

export function windowResize(downCb: Function, upCb: Function): void {
  var clientHeight = window.innerHeight;
  downCb = typeof downCb === 'function' ? downCb : function () { }
  upCb = typeof upCb === 'function' ? upCb : function () { }
  window.addEventListener('resize', () => {
    var height = window.innerHeight;
    if (height === clientHeight) {
      downCb();
    }
    if (height < clientHeight) {
      upCb();
    }
  });
}

/**
 * @name: Merge Arrays
 * @param  {Array} array1 The first array to merge.
 * @param  {Array} array2 The second array to merge.
 * @return {Array} The merged array.
 */
export function mergeArrays(arr1: Array<any>, arr2: Array<any>): Array<any> {
  const newArray = [...arr1, ...arr2];
  return newArray;
}