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; }