function contains (target, str, separator) { return separator ? (separator + target + separator).indexOf(separator + str + separator) > -1 : target.indexOf(str) > -1; }
function startsWith (target, str, ignorecase) { var start_str = target.substr(0, str.length); return ignorecase ? start_str.toLowerCase() === str.toLowerCase() : start_str === str; }
function endsWith (target, str, ignorecase) { var end_str = target.substring(target.length - str.length); return ignorecase ? end_str.toLowerCase() === str.toLowerCase() : end_str === str; }
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: 取得一個字符串全部字節的長度(來自騰訊的解決方案。騰訊經過多子域名+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; }
用於對字符串進行截斷處理,當超過限定長度,默認添加三個點號。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); }
轉換爲駝峯風格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(); }); }
轉換爲下劃線風格前端
function underscored (target) { return target.replace(/([a-z\d])([A-Z])/g, '$1_$2'). replace(/\-/g, '_').toLowerCase(); }
function dasherize (target) { return underscored(target).replace(/_/g, '-'); }
首字母大寫java
function capitalize(target) { return target.charAt(0).toUpperCase() + target.substring(1).toLowerCase(); }
移除字符串中的 html 標籤,但這方法有缺陷,如裏面有 script 標籤,會把這 些不應顯示出來的腳本也顯示出來。在 Prototype.js 中,它與 strip、stripScripts 是一組方法。jquery
function stripTags (target) { return String(target || "").replace(/<[^>]+>/g, ''); }
移除字符串中全部的 script 標籤。彌補 stripTags 方法的缺陷。此方法應 在 stripTags 以前調用。git
function stripScripts (target) { return String(target || "").replace(/<script[^>]*>([\S\s]*?)<\/script>/img, '') }
將字符串通過 html 轉義獲得適合在頁面中顯示的內容,如將<替換 爲 <。github
function escapeHTML (target) { return target.replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, """) .replace(/'/g, "'"); }
將字符串中的 html 實體字符還原爲對應字符。json
function escapeHTML (target) { return target.replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, """) .replace(/'/g, "'"); //IE下不支持'(單引號)轉義 }
function escapeRegExp (target) { return target.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); }
// 簡潔 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 : ''; }
與 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 軟換行。不過須要注意的是,它並非在每一個字符以後都 插入
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
輕量字符串模版
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"
在字符串兩端添加雙引號,而後內部須要轉義的地方都要轉義,用於接裝 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') + '"'; }
數組元素交換位置
/** * 數組元素交換位置 * @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; }
用法同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; }
const toQueryString = obj => Object.keys(obj).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');
千分位分割
function splitBit (num) { var c = (num.toString().indexOf ('.') !== -1) ? num.toLocaleString() : num.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,'); return c; }
節流函數
應用場景:多數在監聽頁面元素滾動事件的時候會用到。由於滾動事件,是一個高頻觸發的事件。
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; }
防抖函數
應用場景:最多見的就是用戶註冊時候的手機號碼驗證和郵箱驗證了。只有等用戶輸入完畢後,前端才須要檢查格式是否正確,若是不正確,再彈出提示語。
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); } }; }
function isType (value, type) { return ({}).toString.call(value) === '[object ' + type + ']'; }
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]; // 火狐 }
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; }
function modifyCSS (dom, css) { if (dom) { for (var key in css) { if (css.hasOwnProperty(key)) { dom.style[key] = css[key]; } } } return dom; }
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; } }
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); } }
/** * 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; } }
設置透明度
function setOpacity (elem, value) { elem.filters ? elem.style.filter = 'alpha(opacity=' + value + ')' : elem.style.opacity = value / 100; }
得到當前視口距離頁面頂部的像素
function getScrollTop () { return document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop }
得到當前視口距離頁面左邊的像素
function getScrollLeft () { return document.documentElement.scrollLeft || window.pageXOffset || document.body.scrollLeft }
/** * 添加事件監聽器 * @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); } }; } } }
document.onkeypress = function(e){ e = e || window.event; console.log(e.keyCode || e.which); // 常規瀏覽器 || IE }
阻止事件冒泡
function stopProp (event) { event = event || window.event; event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; // 常規瀏覽器 || IE };
阻止瀏覽器默認行爲,如:按標籤連接跳轉
function preDef (event) { event = event || window.event event.preventDefault ? event.preventDefault() : event.returnValue = false // 常規瀏覽器 | IE }
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; }