工具函數

String

contains

function contains (target, str, separator) {
    return separator ? (separator + target + separator).indexOf(separator + str + separator) > -1 : target.indexOf(str) > -1;
}

startsWith

function startsWith (target, str, ignorecase) {
    var start_str = target.substr(0, str.length);
    return ignorecase ? start_str.toLowerCase() === str.toLowerCase() : start_str === str;
}

endsWith

function endsWith (target, str, ignorecase) {
    var end_str = target.substring(target.length - str.length);
    return ignorecase ? end_str.toLowerCase() === str.toLowerCase() : end_str === str;
}

repeat

function repeat (target, n) {
    var s = target,
        total = "";
    while (n > 0) {
        if (n % 2 == 1)
            total += s;
        if (n == 1)
            break;
        s += s;
        n = n >> 1;
    }
    return total;
}

byteLen

byteLen: 取得一個字符串全部字節的長度(來自騰訊的解決方案。騰訊經過多子域名+postMessage+manifest 離線 proxy 頁面的 方式擴大 localStorage 的存儲空間,在這過程當中須要知道用戶已經存了多少東西,所以,咱們就 必須編寫一個嚴謹的 byteLen 方法。)javascript

/** *
* http://www.alloyteam.com/2013/12/js-calculate-the-number-of-bytes-occupied-by-a-str ing/
* 計算字符串所佔的內存字節數,默認使用 UTF-8 的編碼方式計算,也可制定爲 UTF-16
* UTF-8 是一種可變長度的 Unicode 編碼格式,使用 1 至 4 個字節爲每一個字符編碼 *
* 000000 - 00007F(128個代碼)
* 000080 - 0007FF(1920個代碼) 
* 000800 - 00D7FF 00E000 - 00FFFF(61440個代碼) 0zzzzzzz(00-7F) 一個字節 110yyyyy(C0-DF) 10zzzzzz(80-BF) 兩個字節 1110xxxx(E0-EF) 10yyyyyy 10zzzzzz 3個字節
* 010000 - 10FFFF(1048576 個代碼) 11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz 4 個字節 *
* 注: Unicode 在範圍 D800-DFFF 中不存在任何字符
* {@link <a onclick="javascript:pageTracker._trackPageview('/outgoing/zh.wikipedia.org/wiki/UTF -8');"
* href="http://zh.wikipedia.org/wiki/UTF-8">http://zh.wikipedia.org/wiki/UTF-8</a>} *
* UTF-16 大部分使用兩個字節編碼,編碼超出 65535 的使用 4 個字節
* 000000 - 00FFFF 兩個字節
* 010000 - 10FFFF 4 個字節
* {@link <a onclick="javascript:pageTracker._trackPageview('/outgoing/zh.wikipedia.org/wiki/UTF-16');" 
* href="http://zh.wikipedia.org/wiki/UTF-16">http://zh.wikipedia.org/wiki/UTF-16</a>} * @param {String} str
* @param {String} charset utf-8, utf-16
* @return {Number}
*/
function byteLen(str, charset) {
    var total = 0,
        charCode,
        i,
        len;
    charset = charset ? charset.toLowerCase() : '';
    if (charset === 'utf-16' || charset === 'utf16') {
        for (i = 0, len = str.length; i < len; i++) {
            charCode = str.charCodeAt(i);
            if (charCode <= 0xffff) {
                total += 2;
            } else {
                total += 4;
            }
        }
    } else {
        for (i = 0, len = str.length; i < len; i++) {
            charCode = str.charCodeAt(i);
            if (charCode <= 0x007f) {
                total += 1;
            } else if (charCode <= 0x07ff) {
                total += 2;
            } else if (charCode <= 0xffff) {
                total += 3;
            } else {
                total += 4;
            }
        }
    }
    return total;
}

truncate

用於對字符串進行截斷處理,當超過限定長度,默認添加三個點號。css

function truncate (target, length, truncation) {
    length = length || 30;
    truncation = truncation === void(0) ? '...' : truncation;
    return target.length > length ? target.slice(0, length - truncation.length) + truncation : String(target);
}

camelize

轉換爲駝峯風格html

function camelize (target) {
    if (target.indexOf('-') < 0 && target.indexOf('_') < 0) {
        return target; //提早判斷,提升getStyle等的效率
    }
    return target.replace(/[-_][^-_]/g, function(match) {
        return match.charAt(1).toUpperCase();
    });
}

underscored

轉換爲下劃線風格前端

function underscored (target) {
    return target.replace(/([a-z\d])([A-Z])/g, '$1_$2').
    replace(/\-/g, '_').toLowerCase();
}

dasherize

function dasherize (target) {
    return underscored(target).replace(/_/g, '-');
}

capitalize

首字母大寫java

function capitalize(target) {
    return target.charAt(0).toUpperCase() + target.substring(1).toLowerCase();
}

stripTags

移除字符串中的 html 標籤,但這方法有缺陷,如裏面有 script 標籤,會把這 些不應顯示出來的腳本也顯示出來。在 Prototype.js 中,它與 strip、stripScripts 是一組方法。jquery

function stripTags (target) {
    return String(target || "").replace(/<[^>]+>/g, '');
}

stripScripts

移除字符串中全部的 script 標籤。彌補 stripTags 方法的缺陷。此方法應 在 stripTags 以前調用。git

function stripScripts (target) {
    return String(target || "").replace(/<script[^>]*>([\S\s]*?)<\/script>/img, '')
}

escapeHTML

將字符串通過 html 轉義獲得適合在頁面中顯示的內容,如將<替換 爲 <。github

function escapeHTML (target) {
    return target.replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#39;");
}

unescapeHTML

將字符串中的 html 實體字符還原爲對應字符。json

function escapeHTML (target) {
    return target.replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#39;"); //IE下不支持&apos;(單引號)轉義
}

escapeRegExp

function escapeRegExp (target) {
    return target.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
}

trim

// 簡潔
function trim (str) {
    return str.replace(/^\s+|\s+$/g, '');
}
function trim (string) {
    // uFEFF:字節順序標記(英語:byte-order mark,BOM)是位於碼點U+FEFF的統一碼字符的名稱。當以UTF-16或UTF-32來將UCS/統一碼字符所組成的字符串編碼時,這個字符被用來標示其字節序。它常被用來當作標示文件是以UTF-八、UTF-16或UTF-32編碼的記號。
    return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '');
};
// 速度快
function trim (str) {
    var whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\n\
\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000';
    for (var i = 0; i < str.length; i++) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(i);
            break;
        }
    }
    for (i = str.length - 1; i >= 0; i--) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(0, i + 1);
            break;
        }
    }
    return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
}

pad

與 trim 相反,pad 能夠爲字符串的某一端添加字符串。api

function pad (target, n, filling, right, radix) {
    var num = target.toString(radix || 10);
    filling = filling || "0";
    while (num.length < n) {
        if (!right) {
            num = filling + num;
        } else {
            num += filling;
        }
    }
    return num;
}

wbr

爲目標字符串添加 wbr 軟換行。不過須要注意的是,它並非在每一個字符以後都 插入字樣,而是至關於在組成文本節點的部分中的每一個字符後插入字樣。如 aabbcc,返回 aabbcc。另外, 在 Opera 下,瀏覽器默認 css 不會爲 wbr 加上樣式,致使沒有換行效果,能夠在 css 中加上 wbr: after { content: "\00200B" } 解決此問題。

function wbr (target) {
    return String(target).replace(/(?:<[^>]+>)|(?:&#?[0-9a-z]{2,6};)|(.{1})/gi, '$&<wbr>').replace(/><wbr>/g, '>');
}

!> 注:IE僅6-7兼容此標籤 https://caniuse.com/#search=wbr

format

輕量字符串模版

function format (str, object) {
    var array = Array.prototype.slice.call(arguments, 1);
    return str.replace(/\\?\#{([^{}]+)\}/gm, function(match, name) {
        if (match.charAt(0) == '\\')
            return match.slice(1);
        var index = Number(name)
        if (index >= 0)
            return array[index];
        if (object && object[name] !== void 0)
            return object[name];
        return '';
    });
}

Example:

var a = format("Result is #{0},#{1}", 22, 33);
console.log(a); //"Result is 22,33"
var b = format("#{name} is a #{sex}", {
    name: "Jhon",
    sex: "man"
});
console.log(b); //"Jhon is a man"

quote

在字符串兩端添加雙引號,而後內部須要轉義的地方都要轉義,用於接裝 JSON 的鍵名或模析系統中。

// 原生方法,須要瀏覽器支持原生JSON
JSON.stringify
//http://code.google.com/p/jquery-json/
var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g,
    meta = {
        '\b': '\\b',
        '\t': '\\t',
        '\n': '\\n',
        '\f': '\\f',
        '\r': '\\r',
        '"': '\\"',
        '\\': '\\\\'
    };

function quote (target) {
    if (target.match(escapeable)) {
        return '"' + target.replace(escapeable, function(a) {
            var c = meta[a];
            if (typeof c === 'string') {
                return c;
            }
            return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4)
        }) + '"';
    }
    return '"' + target + '"';
}
//https://github.com/ecomfe/etpl/blob/2.1.0/src/main.js#L207 
function stringLiteralize (source) {
    return '"' +
        source
        .replace(/\x5C/g, '\\\\')
        .replace(/"/g, '\\"')
        .replace(/\x0A/g, '\\n')
        .replace(/\x09/g, '\\t')
        .replace(/\x0D/g, '\\r') + '"';
}

Array

數組元素交換位置

/**
* 數組元素交換位置
* @param {array} arr 數組
* @param {number} index1 添加項目的位置
* @param {number} index2 刪除項目的位置
* index1和index2分別是兩個數組的索引值,便是兩個要交換元素位置的索引值,如1,5就是數組中下標爲1和5的兩個元素交換位置
*/
function swapItem (arr, index1, index2) {
    arr[index1] = arr.splice(index2, 1, arr[index1])[0];
    return arr;
}

Object

get

用法同lodash的get

function get (object, path, defaultValue) {
    return (!Array.isArray(path) ? path.replace(/\[/g, '.').replace(/\]/g, '').split('.') : path)
            .reduce((obj, key) => (obj || {})[key], object) || defaultValue;
}

toQueryString

const toQueryString = obj => Object.keys(obj).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');

Number

splitBit

千分位分割

function splitBit (num) {
    var c = (num.toString().indexOf ('.') !== -1) ? num.toLocaleString() : num.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
    return c;
}

Function

throttle

節流函數
應用場景:多數在監聽頁面元素滾動事件的時候會用到。由於滾動事件,是一個高頻觸發的事件。

function throttle (func, wait, options) {
  var timeout = void 0,
      context = void 0,
      args = void 0,
      result = void 0;
  var previous = 0;
  if (!options) options = {};

  var later = function later() {
    previous = options.leading === false ? 0 : Date.now();
    timeout = null;
    result = func.apply(context, args);
    if (!timeout) context = args = null;
  };

  var throttled = function throttled() {
    var now = Date.now();
    if (!previous && options.leading === false) previous = now;
    var remaining = wait - (now - previous);
    context = this;
    args = arguments;
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = now;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    } else if (!timeout && options.trailing !== false) {
      timeout = setTimeout(later, remaining);
    }
    return result;
  };

  throttled.cancel = function () {
    clearTimeout(timeout);
    previous = 0;
    timeout = context = args = null;
  };

  return throttled;
}

debounce

防抖函數
應用場景:最多見的就是用戶註冊時候的手機號碼驗證和郵箱驗證了。只有等用戶輸入完畢後,前端才須要檢查格式是否正確,若是不正確,再彈出提示語。

function debounce (fn, context) {
  fn.tId && clearTimeout(fn.tId)
  fn.tId = setTimeout((() => {
    fn.call(context)
  }, 500)
}
function debounce(func, wait, immediate) {
  var timeout = void 0;
  return function () {
    var context = this,
        args = arguments;
    var later = function later() {
      timeout = null;
      if (!immediate) {
        func.apply(context, args);
      }
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) {
      func.apply(context, args);
    }
  };
}

Lang

isType

function isType (value, type) {
  return ({}).toString.call(value) === '[object ' + type + ']';
}

Dom

getStyle

function getStyle (dom, styleName) {
    if (!dom || !styleName) return null;
        styleName = camelize(styleName);
        if (styleName === 'float') {
            styleName = 'cssFloat';
        }
    /**
    * let style = window.getComputedStyle(dom, null);
    * 它等價於
    * let style = document.defaultView.getComputedStyle(dom, null);
    */
    return dom.currentStyle ? dom.currentStyle[styleName] : getComputedStyle(dom, null)[styleName]; // 火狐
}

getWidth

function getWidth (dom) {
    let stl = root.currentStyle || document.defaultView.getComputedStyle(dom);
    return ((dom.clientWidth || parseInt(stl.width, 10)) - parseInt(stl.paddingLeft, 10) - parseInt(stl.paddingRight, 10)).toFixed(0) - 0;
}

modifyCSS

function modifyCSS (dom, css) {
  if (dom) {
    for (var key in css) {
      if (css.hasOwnProperty(key)) {
        dom.style[key] = css[key];
      }
    }
  }
  return dom;
}

hasClass

function hasClass (el, cls) {
    if (!el || !cls) {return false;}
    if (cls.indexOf(' ') !== -1) {throw new Error('className should not contain space.');}
    if (el.classList) {
        return el.classList.contains(cls);
    } else {
        return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
    }
}

removeClass

function removeClass (el, cls) {
    if (!el || !cls) {return;}
    const classes = cls.split(' ');
    let curClass = ' ' + el.className + ' ';

    for (let i = 0, j = classes.length; i < j; i++) {
        const clsName = classes[i];
        if (!clsName) {continue;}

        if (el.classList) {
            el.classList.remove(clsName);
        } else {
            if (hasClass(el, clsName)) {
                curClass = curClass.replace(' ' + clsName + ' ', ' ');
            }
        }
    }
    if (!el.classList) {
        el.className = trim(curClass);
    }
}

addClass

/**
 * Created by linqiang on 2019/6/5.
 */
function addClass (el, cls) {
    if (!el) {return;}
    let curClass = el.className;
    const classes = (cls || '').split(' ');
    for (let i = 0, j = classes.length; i < j; i++) {
        const clsName = classes[i];
        if (!clsName) {continue;}
        if (el.classList) {
            el.classList.add(clsName);
        } else {
            if (!hasClass(el, clsName)) {
                curClass += ' ' + clsName;
            }
        }
    }
    if (!el.classList) {
        el.className = curClass;
    }
}

setOpacity

設置透明度

function setOpacity (elem, value) {
    elem.filters ? elem.style.filter = 'alpha(opacity=' + value + ')' : elem.style.opacity = value / 100;
}

getScrollTop

得到當前視口距離頁面頂部的像素

function getScrollTop () {
    return document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
}

getScrollLeft

得到當前視口距離頁面左邊的像素

function getScrollLeft () {
    return document.documentElement.scrollLeft || window.pageXOffset || document.body.scrollLeft
}

addEventListener

/**
 * 添加事件監聽器
 * @param  {Object} target DOM對象
 * @param  {String} eventType 事件名
 * @param  {Funtion} callback 回調函數
 * @return {Object} 返回對象
 */
function addEventListener (target, eventType, callback) {
  if (target) {
    if (target.addEventListener) {
      target.addEventListener(eventType, callback, false);
      return {
        remove: function remove() {
          target.removeEventListener(eventType, callback, false);
        }
      };
    } else if (target.attachEvent) {
      target.attachEvent('on' + eventType, callback);
      return {
        remove: function remove() {
          target.detachEvent('on' + eventType, callback);
        }
      };
    }
  }
}

getKeyCode

document.onkeypress = function(e){  
    e = e || window.event;  
    console.log(e.keyCode || e.which);  // 常規瀏覽器 || IE  
}

stopProp

阻止事件冒泡

function stopProp (event) {
    event = event || window.event;
    event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;  // 常規瀏覽器 || IE
};

preDef

阻止瀏覽器默認行爲,如:按標籤連接跳轉

function preDef (event) {
    event = event || window.event
    event.preventDefault ? event.preventDefault() : event.returnValue = false // 常規瀏覽器 | IE
}

isIE6

IE6斷定

function isIE6 () {
    //在IE6中[-1,].toString()爲「1,」,‘-’會進行類型轉換(轉成數字類型),-"1,"  爲NaN,因此返回!false 
    //非IE6   非IE6中[-1,].toString()爲「1」,‘-’會進行類型轉換(轉成數字類型),-"1"  爲-1,因此返回!true
    return !-[1,];
}

斷定IE瀏覽器

function isIE () {
    //由於VB是微軟發明的,其餘瀏覽器無VBArray,至少可斷定IE 6/7/8/9/10  
    return !!window.VBArray;
}
相關文章
相關標籤/搜索