工具函数

判断当前终端是否PC


export const isPC = () => {

  const userAgentInfo = navigator.userAgent;

  const Agents = ['Android', 'webOS', 'BlackBerry', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];

  let bool = true;

  for (let i = 0; i < Agents.length; i++) {

      if (userAgentInfo.indexOf(Agents[i]) > 0) {

      bool = false;

      break;

      }

  }

  return bool;

};

判断当前设备平台


export const isPlatform = () => {

  const ua = window.navigator.userAgent.toLocaleLowerCase();

  const isIOS = /iphone|ipad|ipod/.test(ua);

  const isAndroid = /android/.test(ua);

  return {

    isIOS,

    isAndroid,

  };

};

判断当前浏览器类型


export const isBrowser = () => {

  let [isIE, isFirefox, isChrome, isOpera, isSafari] = [0, 0, 0, 0, 0];

  if (window.ActiveXObject) {

    isIE = 1;

  }

  if (document.getBoxObjectFor) {

    isFirefox = 1;

  }

  if (window.MessageEvent && !document.getBoxObjectFor) {

    isChrome = 1;

  }

  if (window.opera) {

    isOpera = 1;

  }

  if (window.openDatabase) {

    isSafari = 1;

  }

  return {

    isIE,

    isChrome,

    isFirefox,

    isOpera,

    isSafari,

  };

};

获取浏览器版本信息


export const getBrowserInfo = () => {

  const ua = navigator.userAgent;

  const ret = {};

  const webkit = ua.match(/WebKit\/([\d.]+)/);

  const chrome = ua.match(/Chrome\/([\d.]+)/)

    || ua.match(/CriOS\/([\d.]+)/);

  const ie = ua.match(/MSIE\s([\d\.]+)/)

    || ua.match(/(?:trident)(?:.*rv:([\w.]+))?/i);

  const firefox = ua.match(/Firefox\/([\d.]+)/);

  const safari = ua.match(/Safari\/([\d.]+)/);

  const opera = ua.match(/OPR\/([\d.]+)/);

  if (webkit) {

    ret.webkit = webkit[1];

  }

  if (chrome) {

    ret.chrome = chrome[1];

  }

  if (ie) {

    ret.ie = ie[1];

  }

  if (firefox) {

    ret.firefox = firefox[1];

  }

  if (safari) {

    ret.safari = safari[1];

  }

  if (opera) {

    ret.opera = opera[1];

  }

  return ret;

};

判断是否IphoneX


export const isIphonex = () => {

  if (typeof window !== 'undefined' && window) {

    return /iphone/gi.test(window.navigator.userAgent) && window.screen.height >= 812;

  }

  return false;

};

移动端键盘适配方案


/**

* 监听输入框的软键盘弹起和收起事件

* @param {*} $input

*/

export const listenKeyboard = ($input) => {

  const { isIOS, isAndroid } = isPlatform();

  if (isIOS) {

    $input.addEventListener('focus', () => {

      // console.log('IOS 键盘弹起');

    }, false);

    // IOS 键盘收起:IOS 点击输入框以外区域或点击收起按钮,输入框都会失去焦点,键盘会收起

    $input.addEventListener('blur', () => {

      // console.log('IOS 键盘收起');

      // 微信浏览器版本6.7.4+IOS12会出现键盘收起后,视图被顶上去了没有下来

      const wechatInfo = window.navigator.userAgent.match(/MicroMessenger\/([\d\.]+)/i);

      if (!wechatInfo) return;

      const wechatVersion = wechatInfo[1];

      const version = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);

      if (+wechatVersion.replace(/\./g, '') >= 674 && +version[1] >= 12) {

        setTimeout(() => {

          window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));

        });

      }

    }, false);

  }

  // Andriod 键盘收起:Andriod 键盘弹起或收起页面高度会发生变化,以此为依据获知键盘收起

  if (isAndroid) {

    let originHeight = document.documentElement.clientHeight || document.body.clientHeight;

    window.addEventListener('resize', () => {

      const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;

      if (originHeight < resizeHeight) {

        // console.log('android 键盘收起了');

      } else {

        // console.log('android 键盘弹起了');

      }

      originHeight = resizeHeight;

    }, false);

  }

};

安卓滚动问题


/**

* 安卓获取到焦点元素滚动到可视区

* @param {*} activeElement

* @param {*} delay

*/

export const activeElementScrollIntoView = (activeElement, delay) => {

  const editable = activeElement.getAttribute('contenteditable');

  // 输入框、textarea或富文本获取焦点后没有将该元素滚动到可视区

  if (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || editable === '' || editable) {

    setTimeout(() => {

      activeElement.scrollIntoView();

    }, delay);

  }

};

mint-ui的popup滑动穿透问题


export const touchController = (bool, $el) => {

  if (bool) {

    $el.addEventListener('touchmove', e => e.preventDefault(), { passive: false });

  } else {

    $el.removeEventListener('touchmove', e => e.preventDefault(), { passive: false });

  }

};

图片转base64


    <input type="file" class="file" @change="imgBroadcastChange" />

    imgBroadcastChange(e){

      if (e && e.target.files[0]) {

      const imgFile = e.target.files[0];

      if (!/image\/\w+/.test(imgFile.type)) {

        showToast('请确保文件为图像类型');

        return;

      }

      uploadImgToBase64(imgFile);

    }

  }

  // 转base64

  static uploadImgToBase64(file) {

    const size = (file.size / 1024) / 1024;

    // if (size > 2) {

    //  showToast('图片太大,超过2M');

    //  return false;

    // }

    return (new Promise((resolve, reject) => {

      const reader = new FileReader();

      reader.readAsDataURL(file);

      // 图片转base64完成后返回reader对象

      reader.onload = () => {

        resolve(reader);

        showToast('发送成功');

      };

      reader.onerror = () => {

        reject(reader);

      };

    }));

  }

图片压缩


const compressImage = (file, success, error) => {

  // 图片小于1M不压缩

  if (file.size < Math.pow(1024, 2)) {

    return success(file);

  }

  // gif图片不压缩

  if (file.type === 'image/gif') {

    return success(file);

  }

  const name = file.name; //文件名

  const reader = new FileReader();

  reader.readAsDataURL(file);

  reader.onload = (e) => {

    const src = e.target.result;

    const img = new Image();

    img.src = src;

    img.onload = (e) => {

      const w = img.width;

      const h = img.height;

      const quality = 0.92;  // 默认图片质量为0.92

      //生成canvas

      const canvas = document.createElement('canvas');

      const ctx = canvas.getContext('2d');

      // 创建属性节点

      const anw = document.createAttribute("width");

      anw.nodeValue = w;

      const anh = document.createAttribute("height");

      anh.nodeValue = h;

      canvas.setAttributeNode(anw);

      canvas.setAttributeNode(anh);

      //铺底色 PNG转JPEG时透明区域会变黑色

      ctx.fillStyle = "#fff";

      ctx.fillRect(0, 0, w, h);

      ctx.drawImage(img, 0, 0, w, h);

      // quality值越小,所绘制出的图像越模糊

      const base64 = canvas.toDataURL('image/jpeg', quality); //图片格式jpeg或webp可以选0-1质量区间

      // 返回base64转blob的值

      console.log(`原图${(src.length / 1024).toFixed(2)}kb`, `新图${(base64.length / 1024).toFixed(2)}kb`);

      //去掉url的头,并转换为byte

      const bytes = window.atob(base64.split(',')[1]);

      //处理异常,将ascii码小于0的转换为大于0

      const ab = new ArrayBuffer(bytes.length);

      const ia = new Uint8Array(ab);

      for (let i = 0; i < bytes.length; i++) {

        ia[i] = bytes.charCodeAt(i);

      }

      file = new Blob([ab], { type: 'image/jpeg' });

      file.name = name;

      success(file);

    }

    img.onerror = (e) => {

      error(e);

    }

  }

  reader.onerror = (e) => {

    error(e);

  }

}

export default compressImage

绑定事件


  /**

  * @description 绑定事件 on(element, event, handler)

  */

  static on = (() => {

    if (document.addEventListener) {

      return (element, event, handler) => {

        if (element && event && handler) {

          element.addEventListener(event, handler, false);

        }

      };

    }

    return (element, event, handler) => {

      if (element && event && handler) {

        element.attachEvent(`on${event}`, handler);

      }

    };

  })();

解绑事件


  /**

  * @description 解绑事件 off(element, event, handler)

  */

  static off = (() => {

    if (document.removeEventListener) {

      return (element, event, handler) => {

        if (element && event) {

          element.removeEventListener(event, handler, false);

        }

      };

    }

    return (element, event, handler) => {

      if (element && event) {

        element.detachEvent(`on${event}`, handler);

      }

    };

  })();

平滑的滚动


  static scrollTop = (el, from = 0, to, duration = 500, endCallback) => {

    const animateFun = callback => window.setTimeout(callback, 1000 / 60);

    if (!window.requestAnimationFrame) {

      window.requestAnimationFrame = (

        window.webkitRequestAnimationFrame

        || window.mozRequestAnimationFrame

        || window.msRequestAnimationFrame

        || animateFun

      );

    }

    const difference = Math.abs(from - to);

    const step = Math.ceil(difference / duration * 50);

    const scroll = (start, end) => {

      if (start === end) {

        if (endCallback) {

          endCallback();

        }

        return;

      }

      let d = (start + step > end) ? end : start + step;

      if (start > end) {

        d = (start - step < end) ? end : start - step;

      }

      if (el === window) {

        window.scrollTo(d, d);

      } else {

        el.scrollTop = d;

      }

      window.requestAnimationFrame(() => scroll(d, end, step));

    };

    scroll(from, to, step);

  };

生成时间表


// 随机时间间隔(秒)

const _interval = (min, max) => {

  return Math.floor(Math.random() * (max - min + 1) + min);

}

// 合并数组

const _flatten = (arr) => {

  return arr.reduce(function (flat, toFlatten) {

    return flat.concat(Array.isArray(toFlatten) ? _flatten(toFlatten) : toFlatten);

  }, []);

}

// 获取时间表

const _getSchedule = (startTime, endTime, startInterval, endInterval) => {

  var times = [];

  var time = startTime;

  while (time > endTime) {

    let betTime = _interval(startInterval, endInterval);

    time -= betTime;

    times.push(time)

    if (time <= endInterval) {

      break;

    }

  }

  return times;

}

// 生成时间表

const _makeTimeSchedule = (duration, currentTime, rate) => {

  let objs = [];

  let proportion = 0;

  let time = duration;

  rate.forEach((item, index) => {

    proportion += (item.rate / 100);

    objs.push(_getSchedule(time,

      time - (time * proportion),

      item.min, item.max));

    time = objs[index][objs[index].length - 1]

  })

  return _flatten(objs).filter((x) => {

    return x < currentTime;

  });;

}

QS转换query参数


// 将{id: 1, token: 123}转换成id=1&token=123这种格式

const.getQueryParams = (obj) => {

  return qs.stringify(obj);

}

// 将id=1&token=123转换成{id: 1, token: 123}这种格式

const.getQueryObj = (str) => {

  return qs.parse(str);

}

获取粘贴板图片数据


const pasteSendImg = (e, success) => {

    e = e || event;

    if (e.originalEvent) {

      e = e.originalEvent;

    }

    const cbd = e.clipboardData;

    const ua = window.navigator.userAgent;

    // 如果是 Safari 直接 return

    if (!(e.clipboardData && e.clipboardData.items)) {

      return;

    }

    // Mac平台下Chrome49版本以下 复制Finder中的文件的Bug Hack掉

    if (cbd.items && cbd.items.length === 2 && cbd.items[0].kind === 'string' && cbd.items[1].kind === 'file'

      && cbd.types && cbd.types.length === 2 && cbd.types[0] === 'text/plain' && cbd.types[1] === 'Files'

      && ua.match(/Macintosh/i) && Number(ua.match(/Chrome\/(\d{2})/i)[1]) < 49) {

      return;

    }

    //文件类型是Files,并且数据格式是image,才进行正常发送

    if (cbd.types[0] === 'Files' && cbd.items[0].type.indexOf('image') >= 0) {

      for (let i = 0; i < cbd.items.length; i++) {

        const item = cbd.items[i];

        if (item.kind === 'file') {

          const blob = item.getAsFile();

          if (blob.size === 0) {

            return;

          }

          success(blob);

          // blob 就是从剪切板获得的文件 可以进行上传或其他操作

        }

      }

    }

  }

根据区间随机数


  /**

  * 根据区间随机数

  */

  static randomNumber = (min, max) => Math.floor(Math.random() * (max - min) + min);

通过JSON实现深拷贝(会忽略掉函数)


static deepclone = (target, origin)=> {

    target = JSON.parse(JSON.stringify(origin));

    return target;

}

获取滚动条距顶部的距离


/**

*

* @desc 获取滚动条距顶部的距离

*/

function getScrollTop() {

    return (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;

}

module.exports = getScrollTop;

设置滚动条距顶部的距离




/**

*

* @desc 设置滚动条距顶部的距离

* @param {Number} value

*/

function setScrollTop(value) {

    window.scrollTo(0, value);

    return value;

}

module.exports = setScrollTop;

获取一个元素的距离文档(document)的位置,类似jQ中的offset()


/**

*

* @desc  获取一个元素的距离文档(document)的位置,类似jQ中的offset()

* @param {HTMLElement} ele

* @returns { {left: number, top: number} }

*/

function offset(ele) {

    var pos = {

        left: 0,

        top: 0

    };

    while (ele) {

        pos.left += ele.offsetLeft;

        pos.top += ele.offsetTop;

        ele = ele.offsetParent;

    };

    return pos;

}

module.exports = offset;

{duration}时间内,滚动条平滑滚动到{to}指定位置

这里用到上面的getScrollTop和setScrollTop


var getScrollTop = require('./getScrollTop');

var setScrollTop = require('./setScrollTop');

var requestAnimFrame = (function () {

    return window.requestAnimationFrame ||

        window.webkitRequestAnimationFrame ||

        window.mozRequestAnimationFrame ||

        function (callback) {

            window.setTimeout(callback, 1000 / 60);

        };

})();

/**

*

* @desc  在${duration}时间内,滚动条平滑滚动到${to}指定位置

* @param {Number} to

* @param {Number} duration

*/

function scrollTo(to, duration) {

    if (duration < 0) {

        setScrollTop(to);

        return

    }

    var diff = to - getScrollTop();

    if (diff === 0) return

    var step = diff / duration * 10;

    requestAnimFrame(

        function () {

            if (Math.abs(step) > Math.abs(diff)) {

                setScrollTop(getScrollTop() + diff);

                return;

            }

            setScrollTop(getScrollTop() + step);

            if (diff > 0 && getScrollTop() >= to || diff < 0 && getScrollTop() <= to) {

                return;

            }

            scrollTo(to, duration - 16);

        });

}

module.exports = scrollTo;

H5软键盘缩回、弹起回调


/**

*

* @desc H5软键盘缩回、弹起回调

* 当软件键盘弹起会改变当前 window.innerHeight,监听这个值变化

* @param {Function} downCb 当软键盘弹起后,缩回的回调

* @param {Function} upCb 当软键盘弹起的回调

*/

function windowResize(downCb, upCb) {

  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();

    }

  });

}

module.exports = windowResize;

函数节流。


/**

* 函数节流

* @param {*} fn

* @param {*} gaptime

*/

function throttle(fn, gaptime) {

    var timer;

    var last;

    return function() {

        var now = +new Date();

        var context = this;

        var args = arguments;

        if(last && now < last + gaptime) {

            clearTimeout(timer);

            timer = setTimeout(function(){

                last = now;

                fn.apply(context, args);

            }, gaptime)

        }else {

            last = now;

            fn.apply(context, args);

        }

    }

}

var fn = function(){

    console.log('hello' + new Date())

}

setInterval(throttle(fn, 2000), 1000)

函数防抖


/* 事件停止被触发N秒后才会再次触发回调

* @param {Function} func - 回调执行函数

* @param {String} wait - 触发间隔

* @param {Boolean} immediate - 是否延时执行

*/

function debounce(func, wait, immediate) {

    var timeout;

    return function() {

        var context = this, args = arguments;

        var later = function() {

            timeout = null;

            if (!immediate) func.apply(context, args);

        };

        var callNow = immediate && !timeout;

        clearTimeout(timeout);

        timeout = setTimeout(later, wait);

        if (callNow) func.apply(context, args);

    };

};

// Usage

var myEfficientFn = debounce(function() {

    // todo

}, 250);

window.addEventListener('resize', myEfficientFn);

判读对象Obj是否为空




/**

*

* @desc  判断`obj`是否为空

* @param  {Object} obj

* @return {Boolean}

*/

function isEmptyObject(obj) {

    if (!obj || typeof obj !== 'object' || Array.isArray(obj))

        return false

    return !Object.keys(obj).length

}

module.exports = isEmptyObject

随机生成颜色


/**

*

* @desc 随机生成颜色

* @return {String}

*/

function randomColor() {

    return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);

}

module.exports = randomColor;

判断是否为邮箱地址


/**

*

* @desc  判断是否为邮箱地址

* @param  {String}  str

* @return {Boolean}

*/

function isEmail(str) {

    return /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(str);

}

module.exports = isEmail;

判断是否为身份证号




/**

*

* @desc  判断是否为身份证号

* @param  {String|Number} str

* @return {Boolean}

*/

function isIdCard(str) {

    return /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/.test(str)

}

module.exports = isIdCard

判断是否为手机号


/**

*

* @desc  判断是否为手机号

* @param  {String|Number} str

* @return {Boolean}

*/

function isPhoneNum(str) {

    return /^(\+?0?86\-?)?1[3456789]\d{9}$/.test(str)

}

module.exports = isPhoneNum

判读url地址是否有效


/**

*

* @desc  判断是否为URL地址

* @param  {String} str

* @return {Boolean}

*/

function isUrl(str) {

    return /[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/i.test(str);

}

module.exports = isUrl;

现金额转大写


/**

*

* @desc  现金额转大写

* @param  {Number} n

* @return {String}

*/

function digitUppercase(n) {

    var fraction = ['角', '分'];

    var digit = [

        '零', '壹', '贰', '叁', '肆',

        '伍', '陆', '柒', '捌', '玖'

    ];

    var unit = [

        ['元', '万', '亿'],

        ['', '拾', '佰', '仟']

    ];

    var head = n < 0 ? '欠' : '';

    n = Math.abs(n);

    var s = '';

    for (var i = 0; i < fraction.length; i++) {

        s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');

    }

    s = s || '整';

    n = Math.floor(n);

    for (var i = 0; i < unit[0].length && n > 0; i++) {

        var p = '';

        for (var j = 0; j < unit[1].length && n > 0; j++) {

            p = digit[n % 10] + unit[1][j] + p;

            n = Math.floor(n / 10);

        }

        s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;

    }

    return head + s.replace(/(零.)*零元/, '元')

        .replace(/(零.)+/g, '零')

        .replace(/^整$/, '零元整');

};

module.exports = digitUppercase

判断浏览器是否支持webP格式图片


/**

*

* @desc 判断浏览器是否支持webP格式图片

* @return {Boolean}

*/

function isSupportWebP() {

    return !![].map && document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0;

}

module.exports = isSupportWebP;

格式化${startTime}距现在的已过时间


/**

* @desc  格式化${startTime}距现在的已过时间

* @param  {Date} startTime

* @return {String}

*/

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 '刚刚'

}

module.exports = formatPassTime

格式化现在距${endTime}的剩余时间


/**

* @desc  格式化现在距${endTime}的剩余时间

* @param  {Date} endTime 

* @return {String}

*/

function formatRemainTime(endTime) {

    var startDate = new Date(); //开始时间

    var endDate = new Date(endTime); //结束时间

    var t = endDate.getTime() - startDate.getTime(); //时间差

    var d = 0,

        h = 0,

        m = 0,

        s = 0;

    if (t >= 0) {

        d = Math.floor(t / 1000 / 3600 / 24);

        h = Math.floor(t / 1000 / 60 / 60 % 24);

        m = Math.floor(t / 1000 / 60 % 60);

        s = Math.floor(t / 1000 % 60);

    }

    return d + "天 " + h + "小时 " + m + "分钟 " + s + "秒";

}

module.exports = formatRemainTime

判断是否为闰年


/**

* @desc 是否为闰年

* @param {Number} year

* @returns {Boolean}

*/

function isLeapYear(year) {

  if (0 === year % 4 && (year % 100 !== 0 || year % 400 === 0)) {

    return true

  }

  return false;

}

module.exports = isLeapYear;

判断是否为同一天


/**

* @desc  判断是否为同一天

* @param  {Date} date1

* @param  {Date} date2 可选/默认值:当天

* @return {Boolean}

*/

function isSameDay(date1, date2) {

    if (!date2) {

        date2 = new Date();

    }

    var date1_year = date1.getFullYear(),

        date1_month = date1.getMonth() + 1,

        date1_date = date1.getDate();

    var date2_year = date2.getFullYear(),

        date2_month = date2.getMonth() + 1,

        date2_date = date2.getDate()

    return date1_date === date2_date && date1_month === date2_month && date1_year === date2_year;

}

module.exports = isSameDay

url参数转对象


/**

* @desc  url参数转对象

* @param  {String} url  default: window.location.href

* @return {Object}

*/

function parseQueryString(url) {

    url = !url ? window.location.href : url;

    if(url.indexOf('?') === -1) {

        return {};

    }

    var search = url[0] === '?' ? url.substr(1) : url.substring(url.lastIndexOf('?') + 1);

    if (search === '') {

        return {};

    }

    search = search.split('&');

    var query = {};

    for (var i = 0; i < search.length; i++) {

        var pair = search[i].split('=');

        query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');

    }

    return query;

}

module.exports = parseQueryString

获取操作系统类型


function getOS() {

    var userAgent = 'navigator' in window && 'userAgent' in navigator && navigator.userAgent.toLowerCase() || '';

    var vendor = 'navigator' in window && 'vendor' in navigator && navigator.vendor.toLowerCase() || '';

    var appVersion = 'navigator' in window && 'appVersion' in navigator && navigator.appVersion.toLowerCase() || '';

    if (/iphone/i.test(userAgent) || /ipad/i.test(userAgent) || /ipod/i.test(userAgent)) return 'ios'

    if (/android/i.test(userAgent)) return 'android'

    if (/win/i.test(appVersion) && /phone/i.test(userAgent)) return 'windowsPhone'

    if (/mac/i.test(appVersion)) return 'MacOSX'

    if (/win/i.test(appVersion)) return 'windows'

    if (/linux/i.test(appVersion)) return 'linux'

}

module.exports = getOS;

once

实用的执行一次函数,不用多解释。虽然很简单的函数,但是防止重复加载或者初始化的习惯必须养成。


function once(fn, context) {

    var result;

    return function() {

        if(fn) {

            result = fn.apply(context || this, arguments);

            fn = null;

        }

        return result;

    };

}

// Usage

var canOnlyFireOnce = once(function() {

    console.log('Fired!');

});

poll

很多时候,我们需要了解某个函数的执行状态,并根据状态执行相应的处理。在没有事件通知时,需要以一定的时间间隔轮询执行状态。


/* 轮询条件函数,根据状态执行相应回调

* @param {Function} fn- 条件函数

* @param {Function} callback - 成功回调

* @param {Function} errback - 失败回调

* @param {int} timeout - 超时间隔

* @param {int} interval - 轮询间隔

*/

function poll(fn, callback, errback, timeout, interval) {

    var endTime = Number(new Date()) + (timeout || 2000);

    interval = interval || 100;

    (function p() {

            // If the condition is met, we're done!

            if(fn()) {

                callback();

            }

            // If the condition isn't met but the timeout hasn't elapsed, go again

            else if (Number(new Date()) < endTime) {

                setTimeout(p, interval);

            }

            // Didn't match and too much time, reject!

            else {

                errback(new Error('timed out for ' + fn + ': ' + arguments));

            }

    })();

}

// Usage:  ensure element is visible

poll(

    function() {

        return document.getElementById('lightbox').offsetWidth > 0;

    },

    function() {

        // Done, success callback

    },

    function() {

        // Error, failure callback

    }

);

将一个多维数组进行组合,返回一个新数组


    function doExchange(doubleArrays) {

        var len = doubleArrays.length;

        if (len >= 2) {

            var len1 = doubleArrays[0].length;

            var len2 = doubleArrays[1].length;

            var newlen = len1 * len2;

            var temp = new Array(newlen);

            var index = 0;

            for (var i = 0; i < len1; i++) {

                for (var j = 0; j < len2; j++) {

                    temp[index] = doubleArrays[0][i] +

                        doubleArrays[1][j];

                    index++;

                }

            }

            var newArray = new Array(len - 1);

            for (var i = 2; i < len; i++) {

                newArray[i - 1] = doubleArrays[i];

            }

            newArray[0] = temp;

            console.log(newArray)

            return doExchange(newArray);

        }

        else {

            return doubleArrays[0];

        }

    }

    var temparr = [

            ["0", "1", "2"],

            ["3", "4"],

            ['5','6']

            ];

    var ret = doExchange(temparr);

pc端新开窗口弹窗


const popupWindow = (url, type, w, h) => {

  const left = (window.screen.width / 2) - (w / 2);

  const top = (window.screen.height / 2) - (h / 2);

  return window.open(url, type, `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${top}, left=${left}`);

};

兼容所有浏览器的获取样式的函数


function  getstyle(obj,name){

   if(window.getComputedStyle){

           return getComputedStyle(obj,null)[name];

   }else{

          return obj.currentStyle[name];

     }

}

特别鸣谢:YIXIU;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342