function
记录一些可以复用的函数或代码片段,支持在ES5+的环境中运行。
客户端os检测
// 判断客户端操作系统是win还是mac还是linux
// 判断客户端是否移动设备
// 判断客户端是否微信
var os = (function(p, ua){
var win = !!p.match(/^Win/),
mac = !!p.match(/^Mac/),
linux = p === 'X11' || !!p.match(/^Linux/),
mobile = !(win || mac || linux),
wechat = !!ua.match(/micromessenger/);
return {
win: win,
mac: mac,
linux: linux,
mobile: mobile,
wechat: wechat
};
}(
navigator.platform,
navigator.userAgent.toLowerCase()
));
扩展函数,支持深度拷贝
/**
* @param {boolean} deep 是否深度拷贝,可选参数
* @param {object} dest 目标对象
* @param {object} src 源对象
* @param {object} srcN 源对象N
* @return {object} 返回修改后的目标对象
*/
function extend() {
var args = arguments, deep = false, dest;
if (typeof args[0] === 'boolean') {
deep = Array.prototype.shift.call(args);
};
dest = Array.prototype.shift.call(args);
Array.prototype.forEach.call(args, function (src) {
Object.keys(src).forEach(function (key) {
if (deep && typeof src[key] === 'object' && typeof dest[key] === 'object') {
extend(true, dest[key], src[key]);
} else if (typeof src[key] !== 'undefined') {
dest[key] = src[key];
};
});
});
return dest;
};
遍历对象或数组
/**
* @param {object|array} obj 遍历的对象
* @param {function} fn 处理函数,将会接收到2个参数:value, key
*/
function each(obj, fn){
if(typeof fn !== 'function') return;
if(Array.isArray(obj)){
Array.prototype.forEach.call(obj, fn);
}else if(typeof obj === 'object'){
Object.keys(obj).forEach(function(key){
fn(obj[key], key);
});
};
}
微型模板函数
使用:sub('hello {name}!', { name: 'world' });
==> hello world!
var sub = function(s, o) {
var SUBREGEX = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g;
return s.replace ? s.replace(SUBREGEX, function (match, key) {
return undef(o[key]) ? match : o[key];
}) : s;
};
判断是否数字
function isNumber(s){
return typeof s === 'number' || !!(s && !isNaN(s));
};
判断是否具有指定class
function hasClass(node, cls, context){
// 同时支持Node和选择器
if(typeof node === 'string'){
node = (context || document).querySelector(node);
};
if(!node || typeof cls !== 'string') return false;
return !!node.className.match(new RegExp('\\b' + cls + '\\b'));
}
命名空间函数,对象的深层属性读写
用法1:
namespace(window, 'location.href') 等价于 window.location.href
用法2:
namespace(window, 'location.href', 'https://a.com') 等价于 window.location.href = 'https://a.com'
function namespace(obj, ns, value) {
// 是否写入模式
var writeMode = arguments.length >= 3;
ns = ns.split(".");
if (writeMode) {
// 写入
let result = obj;
for (var i = 0; i < ns.length; i++) {
let name = ns[i];
if (i === ns.length - 1) {
// 叶子节点,赋值value
obj[name] = value;
} else {
// 空节点设置为{}
if (obj[name] + "" !== "[object Object]") {
obj[name] = {};
}
// 更新游标
obj = obj[name];
}
}
return result;
} else {
// 读取
for (var i = 0; i < ns.length; i++) {
let node = obj[ns[i]];
// 叶子属性
if (i === ns.length - 1) {
// 返回结果
return node;
} else if (node + "" === "[object Object]") {
// 更新游标
obj = node;
} else {
// 提前返回
return undefined;
}
}
}
}
复制到剪贴板
function copy(text, success) {
// 创建一个临时input元素
var el = document.createElement('input');
document.body.appendChild(el);
el.value = text + '';
el.focus();
el.select();
// 兼容iOS
// https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
var range = document.createRange();
var selection = window.getSelection();
el.contentEditable = true;
el.readOnly = false;
range.selectNodeContents(el);
selection.removeAllRanges();
selection.addRange(range);
el.setSelectionRange(0, 999999);
// 拷贝并执行回调函数
if (document.execCommand('copy')) {
if (typeof success === 'function') {
success();
}
}
// 清理
document.body.removeChild(el);
}
版本号判断
判断两个格式为 "10.5.3" 的版本号的大小
如果ver大于等于targetVer,则返回true,否则返回false
function compageVersion(ver, targetVer) {
targetVer = targetVer.split('.');
// 切割字符串,然后逐段比较
return ver.split('.').every(function (v, i) {
var tv = targetVer[i] || '0';
return parseInt(v) >= parseInt(tv);
});
}
取URL参数
取URL中的服务端参数,如果未取到则返回null
function getQueryString(name) {
return (location.search.match(new RegExp('[?&]' + name + '=([^&]*)')) || [])[1];
}