深拷贝
使用JSON.parse(JSON.stringify(object))实现深拷贝局限
1、如果object里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;
2、如果object里有RegExp、Error对象,则序列化的结果将只得到空对象;
3、如果obj里有函数、undefined、symbol,则序列化的结果会把函数或 undefined丢失;
4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
5、JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
6、如果对象中存在循环引用的情况也无法正确实现深拷贝;
解决办法:
1)借用 MessageChannel 实现深拷贝
function deepClone(val) {
return new Promise((resolve,reject) => {
const {port1,port2} = new MessageChannel();
port2.onmessage = e => resolve(e.data);
port1.postMessage(val);
})
}
2) 简单版 递归 copy
function deepCopy(p, c) {
var c = c || {};
for (var i in p) {
if (typeof p[i] === 'object') {
c[i] = (p[i].constructor === Array) ? [] : {};
deepCopy(p[i], c[i]);
} else {
c[i] = p[i];
}
}
return c;
}
3) loadash的 _.cloneDeep()
千位格式化数字
/**
* 每千位格式化
* @param {number}} num
*/
export const toThousands = (num) => {
var result = '', counter = 0;
var dot = String(num).indexOf(".");
if (dot != -1) {
// alert("有小数点");
// 获取小数点后面的数字(indexOf和substring都不支持数字,所以要先转字符串才可以用)
var dotCnt = String(num).substring(dot + 1, num.length);
// 获取小数点前面的数字
num = String(num).split('.')[0]
num = (num || 0).toString();
for (var i = num.length - 1; i >= 0; i--) {
counter++;
result = num.charAt(i) + result;
if (!(counter % 3) && i != 0) { result = ',' + result; }
}
result = result + '.' + dotCnt;
return result;
} else {
// alert("没有小数点");
return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
}
}
判断浏览器
const browser = {
isAndroid: function () {
return !!navigator.userAgent.match(/Android/i)
},
isIOS: function () {
return !!navigator.userAgent.match(/iPhone|iPad|iPod/i)
},
isMobileQQ: function () {
var ua = navigator.userAgent
return /(iPad|iPhone|iPod).*? (IPad)?QQ\/([\d.]+)/.test(ua) || /\bV1_AND_SQI?_([\d.]+)(.*? QQ\/([\d.]+))?/.test(ua)
},
isWx: function () {
return !!navigator.userAgent.match(/micromessenger/i)
},
isChrome: function () {
return !!(navigator.userAgent.match(/Chrome\/([\d.]+)/) || navigator.userAgent.match(/CriOS\/([\d.]+)/))
},
isUC: function () {
return !!navigator.userAgent.match(/UCBrowser/i)
},
isSafari: function () {
return !!navigator.userAgent.match(/safari/i)
},
isQQBrowser: function () {
return !!navigator.userAgent.match(/MQQBrowser/i)
},
isWeibo: function () {
return !!navigator.userAgent.match(/weibo/i)
},
iOSVersion: function () {
var str = navigator.userAgent.toLowerCase();
var ver = str.match(/cpu iphone os (.*?) like mac os/);
return ver ? parseInt(ver[1]) : 0
}
}
动态插入script 标签
export const injectScript = src => {
return new Promise((resolve, reject) => {
const script = document.createElement('script')
script.async = true
script.src = src
script.addEventListener('load', resolve)
script.addEventListener('error', reject)
document.head.appendChild(script)
})
}
获取当前页面的滚动位置
const getScrollPosition = (el = window) => ({
x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
使用:
getScrollPosition(); // {x: 0, y: 200}
平滑滚动到页面的顶部
const scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
}
// 使用
scrollToTop()
点击下载多个文件
延时函数
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
使用a 标签下载
const download = async (url) => {
const a = document.createElement('a');
// a.download = name;
a.href = url;
a.style.display = 'none';
document.body.append(a);
a.click();
// Chrome requires the timeout
await delay(100);
a.remove();
};
使用iframe 下载
setTimeout(function () {
let frame = document.createElement("iframe");
frame.style.display = "none"; // 防止影响页面
frame.style.height = 0;
frame.src = adress;
document.body.appendChild(frame);
setTimeout(function () {
document.body.removeChild(frame);
}, 3000);
}, 100);
循环调用
注:iframe 支持性比较不如a标签
- 解决因为手机设置字体大小导致h5页面在webview中变形的BUG
首先,我们做了一个H5页面,在各种手机浏览器中打开都没问题。我们采用了rem单位进行布局,通过JS来动态计算网页的视窗宽度,动态设置html的font-size,一切都比较完美。
这时候,你自信满满的将h5地址交给了APP工程师,做了一个WEBVIEW嵌套,然后就顺利交工了。
测试组在一堆手机中测试APP,突然,在某个手机上打开,你的页面布局了乱了,字变大或者变小,总之很奇葩。
你怎么也不会想到是手机设置字体大小造成的。
因为默认浏览器中的内容是不受系统字体大小设置控制的,至少我遇到的几台手机都是这样的情况。但是APP不一样,APP是受那个玩意儿控制的!
导致因素:
1.你的页面采用了rem单位,并且是采用js动态计算html的font-size
2.你的页面被加在了APP中的webview中
3.这该死的手机被重设了字体大小
方案一:【h5解决】
需要在设置完字体大小之后,再去重新获取一下html的font-size,这样就可以实现当实际的值与我们设置的值不一样时,根据比例再设置一次。
以下是我的完整代码:
function htmlFontSize(){
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var width = w > h ? h : w;
width = width > 720 ? 720 : width
var fz = ~~(width*100000/36)/10000
document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz +"px";
var realfz = ~~(+window.getComputedStyle(document.getElementsByTagName("html")[0]).fontSize.replace('px','')*10000)/10000
if (fz !== realfz) {
document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz * (fz / realfz) +"px";
}
}
方案二:【安卓android端解决】
安卓客户端通过webview配置webview.getSettings().setTextZoom(100)就可以禁止缩放,按照百分百显示。 webview.getSettings().setTextZoom(100); WebView加上这个设置后,WebView里的字体就不会随系统字体大小设置发生变化了.
手机号隐藏中件位数
var tel = "13122223333";
var reg = /^(\d{3})\d{4}(\d{4})$/;
tel = tel.replace(reg, "$1****$2");
以字节计算 截取字符串
export const sliceStr = (str, length) => {
var realLength = 0, charCode = -1, sliceLength = 0
if(str){
for (var i = 0; i < str.length; i++) {
charCode = str.charCodeAt(i)
if(+realLength < +length){
sliceLength += 1
}
if (charCode >= 0 && charCode <= 128)
realLength += 1
else
realLength += 2
}
}
return {realLength, str, sliceStr: str.slice(0, sliceLength)}
}
格式化数字
export const nFormatter = (num, digits) => {
const si = [
{ value: 1, symbol: "" },
{ value: 1E3, symbol: "K" },
{ value: 1E6, symbol: "M" },
{ value: 1E9, symbol: "G" },
{ value: 1E12, symbol: "T" },
{ value: 1E15, symbol: "P" },
{ value: 1E18, symbol: "E" }
];
let i;
for (i = si.length - 1; i > 0; i--) {
if (num >= si[i].value) {
break;
}
}
//if(num < si[2].value ){
// return num
//}
//return (num / si[i-1].value).toFixed(digits) + si[i-1].symbol;
return (num / si[i].value).toFixed(digits) + si[i].symbol;
}
判断函数
function isJSON(target) {
return typeof target == 'object' && target.constructor == Object;
}
function isArray(o) {
return Object.prototype.toString.call(o) == '[object Array]';
}
function isObject(o){
return Object.prototype.toString.call(o) == '[object Object]'
}
function isString(s){
return Object.prototype.toString.call(s) == '[object String]'
}
树相关函数
// 获取树的广度
function handleGetTreeExtent(node) {
let extend = 0;
node.forEach((item) => {
if (item.children) {
extend += handleGetTreeExtent(item.children);
} else {
extend += 1;
}
});
return extend;
}
// 获取树的深度
function handleGetTreeDeep(fileHeader) {
let deep = 0;
fileHeader.forEach((item) => {
if (item.children) {
deep = Math.max(deep, handleGetTreeDeep(item.children) + 1);
} else {
deep = Math.max(deep, 1);
}
});
return deep;
}
合并两个JSON对象
var objC = {}.constructor;
function isJSON(obj) {
return !!(obj && obj.constructor === objC);
}
var arrC = [].constructor;
function isArr(arr) {
return !!(arr && arr.constructor === arrC);
}
function merge(json1,json2) {
var result = null;
if(isJSON(json2)){
result = {};
if(isJSON(json1)){
for(var key in json1){
if(json1.hasOwnProperty(key)){
result[key] = json1[key];
}
}
}
for(key in json2){
if(json2.hasOwnProperty(key)){
if(typeof result[key] === 'object' && typeof json2[key] === 'object'){
result[key] = merge(result[key],json2[key]);
}else{
result[key] = json2[key];
}
}
}
}else if(isArr(json1) && isArr(json2)){
result = json1;
json2.forEach(function (t) {
if(result.indexOf(t) === -1){
result.push(t);
}
})
}else{
result = json2;
}
return result;
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!