常用的一些工具函数
工具函数
获取当前浏览器支持的tranform的兼容性写法
// 获取当前浏览器支持的transform兼容写法
function getTransform() {
var transform = '',
divStyle = document.createElement('div').style,
// 可能涉及到的几种兼容性写法,通过循环找出浏览器识别的那一个
transformArr = ['transform', 'webkitTransform', 'MozTransform', 'msTransform', 'OTransform'],
i = 0,
len = transformArr.length;
for(; i < len; i++) {
if(transformArr[i] in divStyle) {
// 找到之后立即返回,结束函数
return transform = transformArr[i];
}
}
// 如果没有找到,就直接返回空字符串
return transform;
}
获取元素样式的兼容性写法
function getStyle(elem, property) {
// ie通过currentStyle来获取元素的样式,其他浏览器通过getComputedStyle来获取
return document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(elem, false)[property] : elem.currentStyle[property];
}
函数参数转换为数组
function exam(a, b, c, d, e) {
// 先看看函数的自带属性 arguments 什么是样子的 console.log(arguments); // 使用call/apply将arguments转换为数组, 返回结果为数组,arguments自身不会改变
var arg = [].slice.call(arguments);
console.log(arg);
}
exam(2, 8, 9, 10, 3);
// result:
// { '0': 2, '1': 8, '2': 9, '3': 10, '4': 3 }
// [ 2, 8, 9, 10, 3 ]
// 也常常使用该方法将DOM中的nodelist转换为数组
// [].slice.call( document.getElementsByTagName('li') );
完美处理APP 返回键
var hiddenProperty = 'hidden' in document ? 'hidden' :
1. 'webkitHidden' in document ? 'webkitHidden' :
2. 'mozHidden' in document ? 'mozHidden' :
3. null;
4. var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
5. var onVisibilityChange = function(){
6. if (document[hiddenProperty]) {
7. console.log('页面非激活');
8. }else{
9. console.log('页面激活')
10. }
11. }
12. document.addEventListener(visibilityChangeEvent, onVisibilityChange);
监听汉字输入以及回车搜索
var cpLock = false;
$('#keywordBox').on('compositionstart', function () {
cpLock = true;
});
$('#keywordBox').on('compositionend', function () {
cpLock = false;
});
$('#keywordBox').on('keyup', function () {
if(!cpLock){
$(".ecjia-vip-search .icon-search").click();
}
});
$('#keywordBox').on('keypress', function (event) {
if (event.keyCode == "13"||event.keyCode == "32"||event.keyCode == "8"||event.keyCode == "108") {
$(".ecjia-vip-search .icon-search").click();
}
})
APP跳转H5之后跳回APP
var isMobile = {
Android: function () {
return navigator.userAgent.match(/Android/i) ? true : false;
},
BlackBerry: function () {
return navigator.userAgent.match(/BlackBerry/i) ? true : false;
},
iOS: function () {
return navigator.userAgent.match(/iPhone|iPad|iPod/i) ? true : false;
},
Windows: function () {
return navigator.userAgent.match(/IEMobile/i) ? true : false;
},
any: function () {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Windows());
}
};
$('.bar-tab').on('click','.tab-item ',function(e){
var $items = $('.bar-tab .tab-item');
if($(this).find('.tab-label').html() == "物业社区"){
if (isMobile.iOS()) {
// $(this).attr('href','http://www.baidu.com
// ');
$(this).removeAttr('href');
window.webkit.messageHandlers.go_wysq.postMessage('go_wysq');
}
if (isMobile.Android()) {
$(this).removeAttr('href');
//调用android本地方法
window.android.go_wysq("调用android本地方法fun1FromAndroid(String name)!!");
数组降维
function flattenArray(arr) {
const flattened = [].concat(...arr);
return flattened.some(item => Array.isArray(item)) ?
flattenArray(flattened) : flattened;
}
const arr = [11, [22, 33], [44, [55, 66, [77, [88]], 99]]];
const flatArr = flattenArray(arr); //[11, 22, 33, 44, 55, 66, 77, 88, 99]
数组等长度拆分
var length=Math.ceil(xz.length/12);
for(var i=0,arr=[];i<length;i++){
for(var j=0,arr1=[];j<xz.length;j++){
if(j<12*(i+1)&&j>=12*i){
arr1.push(xz[j])
}
}
arr.push(arr1)
}
循环一个对象的键和值,以url格式输出
function transform(obj) {
var arr = [];
for (var item in obj) {
if (typeof (item) == 'object') {
transform(item);
}
//arr.push(obj[item]);//取出对象的值
arr.push(item+'='+obj[item]);//取出对象的键
}
var str = arr.join("&");
return str;
}
获取URL参数
// 支持获取中文参数
// 获取某一个参数
function getUrlParam(key) {
// 获取参数
var url = window.location.search;
// 正则筛选地址栏
var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
// 匹配目标参数
var result = url.substr(1).match(reg);
//返回参数值
return result ? decodeURIComponent(result[2]) : null;
}
// getUrlParam('key')
// 获取所有的参数为一个对象
function GetUrlParams(){
let url = document.location.toString();
let arrObj = url.split("?");
let params = Object.create(null)
if (arrObj.length > 1){
arrObj = arrObj[1].split("&");
arrObj.forEach(item=>{
item = item.split("=");
params[item[0]] = item[1]
})
}
return params;
}
// ?a=1&b=2&c=3 ==> {a: "1", b: "2", c: "3"}
判断浏览器类型
//运行环境是浏览器
let inBrowser = typeof window !== 'undefined';
//运行环境是微信
let inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform;
let weexPlatform = inWeex && WXEnvironment.platform.toLowerCase();
//浏览器 UA 判断
let UA = inBrowser && window.navigator.userAgent.toLowerCase();
let isIE = UA && /msie|trident/.test(UA);
let isIE9 = UA && UA.indexOf('msie 9.0') > 0;
let isEdge = UA && UA.indexOf('edge/') > 0;
let isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android');
let isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios');
let isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
// 获取浏览器信息
function getExplorerInfo() {
let t = navigator.userAgent.toLowerCase();
return 0 <= t.indexOf("msie") ? { //ie < 11
type: "IE",
version: Number(t.match(/msie ([\d]+)/)[1])
} : !!t.match(/trident\/.+?rv:(([\d.]+))/) ? { // ie 11
type: "IE",
version: 11
} : 0 <= t.indexOf("edge") ? {
type: "Edge",
version: Number(t.match(/edge\/([\d]+)/)[1])
} : 0 <= t.indexOf("firefox") ? {
type: "Firefox",
version: Number(t.match(/firefox\/([\d]+)/)[1])
} : 0 <= t.indexOf("chrome") ? {
type: "Chrome",
version: Number(t.match(/chrome\/([\d]+)/)[1])
} : 0 <= t.indexOf("opera") ? {
type: "Opera",
version: Number(t.match(/opera.([\d]+)/)[1])
} : 0 <= t.indexOf("Safari") ? {
type: "Safari",
version: Number(t.match(/version\/([\d]+)/)[1])
} : {
type: t,
version: -1
}
}
// 微信浏览器
function isWeiXin(){
var ua = window.navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i) == 'micromessenger'){
return true;
}else{
return false;
}
}
// PC 浏览器
function isPCBroswer() {
let e = navigator.userAgent.toLowerCase()
, t = "ipad" == e.match(/ipad/i)
, i = "iphone" == e.match(/iphone/i)
, r = "midp" == e.match(/midp/i)
, n = "rv:1.2.3.4" == e.match(/rv:1.2.3.4/i)
, a = "ucweb" == e.match(/ucweb/i)
, o = "android" == e.match(/android/i)
, s = "windows ce" == e.match(/windows ce/i)
, l = "windows mobile" == e.match(/windows mobile/i);
return !(t || i || r || n || a || o || s || l)
}
JS 获取所需上传文件的本地文件路径
function getImgURL(node) {
var imgURL = "";
try{
var file = null;
if(node.files && node.files[0] ){
file = node.files[0];
}else if(node.files && node.files.item(0)) {
file = node.files.item(0);
}
//Firefox 因安全性问题已无法直接通过input[file].value 获取完整的文件路径
try{
//Firefox7.0
imgURL = file.getAsDataURL();
//alert("//Firefox7.0"+imgRUL);
}catch(e){
//Firefox8.0以上
imgRUL = window.URL.createObjectURL(file);
//alert("//Firefox8.0以上"+imgRUL);
}
}catch(e){ //这里不知道怎么处理了,如果是遨游的话会报这个异常
//支持html5的浏览器,比如高版本的firefox、chrome、ie10
if (node.files && node.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
imgURL = e.target.result;
};
reader.readAsDataURL(node.files[0]);
}
}
//imgurl = imgURL;
creatImg(imgRUL);
return imgURL;
}
function creatImg(imgRUL){ //根据指定URL创建一个Img对象
var textHtml = "<img src='"+imgRUL+"'/>";
$(".mark").html(textHtml);
}
通用柯里化函数
function curry(fn, ...args) {
return (..._arg) => {
return fn(...args, ..._arg);
}
}
手机号加密显示
function hidePhoneNumber(str, frontLen, endLen, cha) {
let len = str.length - frontLen - endLen;
let xing = '';
for (var i = 0; i < len; i++) {
xing += cha;
}
return str.substring(0, frontLen) + xing + str.substring(str.length - endLen);
}
hidePhoneNumber('13888888888',3,4,'*')
数字强制保留两位小数
function returnFloat(value) {
var value = Math.round(parseFloat(value) * 100) / 100;
var xsd = value.toString().split('.');
if (xsd.length == 1) {
value = value.toString() + '.00';
return value;
}
if (xsd.length > 1) {
if (xsd[1].length < 2) {
value = value.toString() + '0';
}
return value;
}
}
returnFloat(5) // 多用于显示金额
禁止右键,选择,复制
["contextmenu", "selectstart", "copy"].forEach(function(ev) {
document.addEventListener(ev, function(event) {
return (event.returnValue = false);
});
});
禁止某些键盘事件
document.addEventListener("keydown", function(event) {
return (
!(
112 == event.keyCode || //F1
123 == event.keyCode || //F12
(event.ctrlKey && 82 == event.keyCode) || //ctrl+R
(event.ctrlKey && 78 == event.keyCode) || //ctrl+N
(event.ctrlKey && 121 == event.keyCode) || //shift+F10
(event.ctrlKey && 115 == event.keyCode) || //alt+F4
("A" == event.srcElement.tagName && event.shiftKey)
) || (event.returnValue = false) //shift+点击a标签
);
});
常用性能分析参数输出
window.onload = function() {
setTimeout(function() {
let t = performance.time;
console.log(
"DNS查询耗时:" + (t.domainLookupEnd - t.domainLookupStart).toFixed(0)
);
console.log("TCP链接耗时:" + (t.connectEnd - t.connectStart).toFixed(0));
console.log(
"request请求耗时:" + (t.responseEnd - t.responseStart).toFixed(0)
);
console.log(
"解析dom树耗时:" + (t.domComplete - t.domInteractive).toFixed(0)
);
console.log("白屏时间:" + (t.responseStart - t.navigationStart).toFixed(0));
console.log(
"domready时间:" +
(t.domContentLoadedEventEnd - t.navigationStart).toFixed(0)
);
console.log(
"onload时间:" + (t.loadEventEnd - t.navigationStart).toFixed(0)
);
if (t == performance.memory) {
console.log(
"js内存使用占比:" +
((t.usedJSHeapSize / t.totalJSHeapSize) * 100).toFixed(0) +
"%"
);
}
});
};
全屏
function toFullScreen(){
let elem = document.body;
elem.webkitRequestFullScreen
? elem.webkitRequestFullScreen()
: elem.mozRequestFullScreen
? elem.mozRequestFullScreen()
: elem.msRequestFullscreen
? elem.msRequestFullscreen()
: elem.requestFullScreen
? elem.requestFullScreen()
: alert("浏览器不支持全屏");
}
退出全屏
function exitFullscreen(){
let elem = parent.document;
elem.webkitCancelFullScreen
? elem.webkitCancelFullScreen()
: elem.mozCancelFullScreen
? elem.mozCancelFullScreen()
: elem.cancelFullScreen
? elem.cancelFullScreen()
: elem.msExitFullscreen
? elem.msExitFullscreen()
: elem.exitFullscreen
? elem.exitFullscreen()
: alert("切换失败,可尝试Esc退出");
}
base64数据导出为文件
function downloadFile(filename, data){
let DownloadLink = document.createElement('a');
if ( DownloadLink ){
document.body.appendChild(DownloadLink);
DownloadLink.style = 'display: none';
DownloadLink.download = filename;
DownloadLink.href = data;
if ( document.createEvent ){
let DownloadEvt = document.createEvent('MouseEvents');
DownloadEvt.initEvent('click', true, false);
DownloadLink.dispatchEvent(DownloadEvt);
}
else if ( document.createEventObject )
DownloadLink.fireEvent('onclick');
else if (typeof DownloadLink.onclick == 'function' )
DownloadLink.onclick();
document.body.removeChild(DownloadLink);
}
}
不同时间格式之间切换
function dateStrForma(str, from, to){
//'20190626' 'YYYYMMDD' 'YYYY年MM月DD日'
str += ''
let Y = ''
if(~(Y = from.indexOf('YYYY'))){
Y = str.substr(Y, 4)
to = to.replace(/YYYY|yyyy/g,Y)
}else if(~(Y = from.indexOf('YY'))){
Y = str.substr(Y, 2)
to = to.replace(/YY|yy/g,Y)
}
let k,i
['M','D','H','h','m','s'].forEach(s =>{
i = from.indexOf(s+s)
k = ~i ? str.substr(i, 2) : ''
to = to.replace(s+s, k)
})
return to
}
// dateStrForma('20190626', 'YYYYMMDD', 'YYYY年MM月DD日') ==> 2019年06月26日
// dateStrForma('121220190626', '----YYYYMMDD', 'YYYY年MM月DD日') ==> 2019年06月26日
// dateStrForma('2019年06月26日', 'YYYY年MM月DD日', 'YYYYMMDD') ==> 20190626
// 一般的也可以使用正则来实现
//'2019年06月26日'.replace(/(\d{4})年(\d{2})月(\d{2})日/, '$1-$2-$3') ==> 2019-06-26
格式化时间
function dateFormater(formater, t){
let date = t ? new Date(t) : new Date(),
Y = date.getFullYear() + '',
M = date.getMonth() + 1,
D = date.getDate(),
H = date.getHours(),
m = date.getMinutes(),
s = date.getSeconds();
return formater.replace(/YYYY|yyyy/g,Y)
.replace(/YY|yy/g,Y.substr(2,2))
.replace(/MM/g,(M<10?'0':'') + M)
.replace(/DD/g,(D<10?'0':'') + D)
.replace(/HH|hh/g,(H<10?'0':'') + H)
.replace(/mm/g,(m<10?'0':'') + m)
.replace(/ss/g,(s<10?'0':'') + s)
}
// dateFormater('YYYY-MM-DD HH:mm', t) ==> 2019-06-26 18:30
// dateFormater('YYYYMMDDHHmm', t) ==> 201906261830
深拷贝(原始类型、时间、正则、错误、数组、对象)
function clone(value, deep){
if(isPrimitive(value)){
return value
}
if (isArrayLike(value)) { //是类数组
value = Array.prototype.slice.call(value)
return value.map(item => deep ? clone(item, deep) : item)
}else if(isPlainObject(value)){ //是对象
let target = {}, key;
for (key in value) {
value.hasOwnProperty(key) && ( target[key] = deep ? clone(value[key], deep) : value[key] )
}
}
let type = getRawType(value)
switch(type){
case 'Date':
case 'RegExp':
case 'Error': value = new window[type](value); break;
}
return value
}
记忆函数
function cached(fn) {
let cache = Object.create(null);
return function cachedFn(str) {
let hit = cache[str];
return hit || (cache[str] = fn(str))
}
}
一维数组组建树形结构
// 平行列表组建树形结构
export const listToTree = (
arr = [],
initId = null,
idKey = 'prod_code',
parentIdKey = 'parent_id',
childrenKey = 'children'
) => {
let children = [];
for (let arrElement of arr) {
if (arrElement != null) {
let currentId = arrElement[idKey];
let parentId = arrElement[parentIdKey];
if (parentId == initId) {
let newChildren = listToTree(arr, currentId, idKey, parentIdKey, childrenKey);
arrElement.children = newChildren;
children.push(arrElement);
}
}
}
};