文件下载
export const download = (res, type, filename) => {
// 创建blob对象,解析流数据
const blob = new Blob([res], {
// 设置返回的文件类型
// type: 'application/pdf;charset=UTF-8' 表示下载文档为pdf,如果是word则设置为msword,excel为excel
type: type
})
// 这里就是创建一个a标签,等下用来模拟点击事件
const a = document.createElement('a')
// 兼容webkix浏览器,处理webkit浏览器中href自动添加blob前缀,默认在浏览器打开而不是下载
const URL = window.URL || window.webkitURL
// 根据解析后的blob对象创建URL 对象
const herf = URL.createObjectURL(blob)
// 下载链接
a.href = herf
// 下载文件名,如果后端没有返回,可以自己写a.download = '文件.pdf'
a.download = filename
document.body.appendChild(a)
// 点击a标签,进行下载
a.click()
// 收尾工作,在内存中移除URL 对象
document.body.removeChild(a)
window.URL.revokeObjectURL(herf)
}
判断真
const isTrue = (k) => {
if (typeof k === 'string') {
return k === 'true';
}
return !!k;
}
过滤对象中的空值
function filterNonNull(obj) {
return Object.fromEntries(Object.entries(obj).filter(([k, v]) => v));
}
const queryString=(qs.stringify(filterNonNull(query)))
忽略ts报错
单行忽略
// @ts-ignore
忽略全文
// @ts-nocheck
取消忽略全文
// @ts-check
字符串转json
function strToJson(str){
var json = (new Function("return " + str))();
return json;
}
//兼容ie
function strToJson(str){
if(!str){
return undefined
}
var json = eval('(' + str + ')');
return json;
}
按字母给对象排序
function objKeySort(obj) {//排序的函数
var newkey = Object.keys(obj).sort();
//先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组
var newObj = {};//创建一个新的对象,用于存放排好序的键值对
for (var i = 0; i < newkey.length; i++) {//遍历newkey数组
newObj[newkey[i]] = obj[newkey[i]];//向新创建的对象中按照排好的顺序依次增加键值对
}
return newObj;//返回排好序的新对象
}
移动端适配
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
移动端隐藏滚动条
html,body{ width: 100%; height: 100%; overflow: scroll;}
html::-webkit-scrollbar, body::-webkit-scrollbar{width:0px;height:0px;}
body{margin:0;}
.yearReport-page::-webkit-scrollbar{width:0px;height:0px;}
获取屏幕缩放比
function detectZoom() {
var ratio = 0,
screen = window.screen,
ua = navigator.userAgent.toLowerCase();
if (window.devicePixelRatio !== undefined) {
ratio = window.devicePixelRatio;
}
else if (~ua.indexOf('msie')) {
if (screen.deviceXDPI && screen.logicalXDPI) {
ratio = screen.deviceXDPI / screen.logicalXDPI;
}
}
else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
ratio = window.outerWidth / window.innerWidth;
}
if (ratio) {
ratio = Math.round(ratio * 100);
}
return ratio/100;
}
echart响应式字体
//获取屏幕宽度并计算比例.按1920传入size
function fontSize(res) {
let clientWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
if (!clientWidth) return;
let fontSize = clientWidth / 1920;
return res * fontSize;
}
rem自适应js
//designWidth:设计稿的实际宽度值,需要根据实际设置
//maxWidth:制作稿的最大宽度值,需要根据实际设置
//这段js的最后面有两个参数记得要设置,一个为设计稿实际宽度,一个为制作稿最大宽度,例如设计稿为750,最大宽度为750,则为(750,750)
;(function(designWidth, maxWidth) {
var doc = document,
win = window,
docEl = doc.documentElement,
remStyle = document.createElement("style"),
tid;
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
maxWidth = maxWidth || 540;
width>maxWidth && (width=maxWidth);
var rem = width * 100 / designWidth;
remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
}
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(remStyle);
} else {
var wrap = doc.createElement("div");
wrap.appendChild(remStyle);
doc.write(wrap.innerHTML);
wrap = null;
}
//要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
refreshRem();
win.addEventListener("resize", function() {
clearTimeout(tid); //防止执行两次
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener("pageshow", function(e) {
if (e.persisted) { // 浏览器后退的时候重新计算
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
if (doc.readyState === "complete") {
doc.body.style.fontSize = "16px";
} else {
doc.addEventListener("DOMContentLoaded", function(e) {
doc.body.style.fontSize = "16px";
}, false);
}
})(750, 750);
js随机色
function randomHexColor() { //随机生成十六进制颜色
return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).substr(-6);
}
jsonp
function jsonp(url, data = {}, callback = 'callback') {
//处理json对象,拼接url
data.jsonpcallback = callback
let params = []
for (let key in data) {
params.push(key + '=' + data[key])
}
let script = document.createElement('script')
script.src = url + '?' + params.join('&')
document.body.appendChild(script)
//返回Promise
return new Promise((resolve, reject) => {
window[callback] = data => {
try {
resolve(data)
} catch (e) {
reject(e)
} finally {
//移除script元素
script.parentNode.removeChild(script)
// window[callback] = null
delete window[callback]
}
}
})
}
字节转化
function bytesToSize(bytes:number) {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return (bytes / (k**i)).toFixed(2) + ' ' + sizes[i];
}
千位分字符
function milliFormat(num) {
return num && num.toString()
.replace(/\d+/, function(s){
return s.replace(/(\d)(?=(\d{3})+$)/g, '$1,')
})
}
删除url指定参数
function removeURLParameter(url, parameter) {
var urlparts = url.split('?');
if(urlparts.length >= 2) {
//参数名前缀
var prefix = encodeURIComponent(parameter) + '=';
var pars = urlparts[1].split(/[&;]/g);
//循环查找匹配参数
for(var i = pars.length; i-- > 0;) {
if(pars[i].lastIndexOf(prefix, 0) !== -1) {
//存在则删除
pars.splice(i, 1);
}
}
return urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : '');
}
return url;
}
css自定义属性
/* 属性定义宽度 */
const data_w = document.querySelectorAll('[data-w]')
for (let i = 0, length = data_w.length; i < length; i++) {
data_w[i].style.width = data_w[i].getAttribute('data-w') + 'px'
}
获取cookie
function getCookie(name){
var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
if(arr != null)
return decodeURI(arr[2]);
return null;
}
写cookie
function setCookie(cName, cValue, days) {
var expires = new Date();
expires.setTime(expires.getTime() + parseInt(days) * 24 * 60 * 60 * 1000);
document.cookie = cName + "=" + escape(cValue) + ";expires=" + expires.toGMTString()+";path=/;domain=xxx.cn";
};
判断客户端
function isPC(){
let userAgentInfo = navigator.userAgent
let Agents = new Array('Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod')
let flag = true
for (let v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break }
}
return flag
}
获取地址栏参数
function getQueryString(name) {
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
let r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
};
return null;
}
正则
域名校验
/^([a-zA-Z\d][a-zA-Z\d-_]+\.)+[a-zA-Z\d-_][^ ]*$/
匹配[开头]结尾
/(?<=\[).*?(?=\])/g
str = str.match(/aaa([\s\S]*?)fff/)[1];
匹配@之前
str = str.match(/(\S*)@/)[1];
匹配@之后
str = str.match(/@(\S*)/)[1];
正则提取ip
const a = /((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/
let str="dsfg[\"0.0.0.0/0\"],fs"
str.match(a)
正则提取邮箱
[a-zA-Z0-9_]{3,20}@[a-zA-Z0-9]{2,10}[.](com|cn|org)
var a1=/[\w-|*]+@[\w]+\.[a-zA-Z0-9]+/
var str1="fasf[\"rr-o@dev.com\"]fkasf"
str1.match(a1)
isTrue
function isTrue(k) {
if (typeof k === 'string') {
return k === 'true';
}
return !!k;
}
防抖函数
/**
* @desc 函数防抖
* @param func 函数
* @param wait 延迟执行毫秒数
* @param immediate true 表立即执行,false 表非立即执行
*/
function debounce(func,wait,immediate) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
}
节流函数
/**
* @desc 函数节流
* @param func 函数
* @param wait 延迟执行毫秒数
* @param type 1 表时间戳版,2 表定时器版
*/
function throttle(fn, wait = 500) {
let prev = 0
return function() {
let args = arguments
let now = Date.now()
if (now - prev > wait) {
console.log(this)//谁调用就指向谁
fn.apply(this, args)
prev = now
}
}
}
深拷贝函数
const deepClone = obj => {
let clone = obj;
if (obj && typeof obj === "object") {
clone = new obj.constructor();
Object.getOwnPropertyNames(obj).forEach(
prop => (clone[prop] = deepClone(obj[prop]))
);
}
return clone;
};
function clone(target, map = new Map()) {
if (typeof target === 'object') {
let cloneTarget = Array.isArray(target) ? [] : {};
if (map.get(target)) {
return map.get(target);
}
map.set(target, cloneTarget);
for (const key in target) {
cloneTarget[key] = clone(target[key], map);
}
return cloneTarget;
} else {
return target;
}
};
转时间格式,到秒
/*new Date()
* @params date
* return str
* */
function formatDateTime(date) {
let y = date.getFullYear();
let m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
let d = date.getDate();
d = d < 10 ? ('0' + d) : d;
let h = date.getHours();
h=h < 10 ? ('0' + h) : h;
let minute = date.getMinutes();
minute = minute < 10 ? ('0' + minute) : minute;
let second=date.getSeconds();
second=second < 10 ? ('0' + second) : second;
return y + '-' + m + '-' + d+' '+h+':'+minute+':'+second;
};
//时间戳格式化
timestampToTime(timestamp) {
let date = new Date(timestamp);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
let Y = date.getFullYear() + '-';
let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
let D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
let h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours())+ ':';
let m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes())+ ':';
let s = date.getSeconds() < 10 ? '0' + date.getMinutes() : date.getMinutes();
return Y + M + D + h + m + s;
},
生成随机验证码
function mkLinks(num){
var str="23QWERTYUIOPASDFGHJKLZXCVBNM1456789zxcvbnmasdfghjklqwertyuiop";
var res='';
for(var i=0;i<num;i++){
res+=str[Math.floor(Math.random()*str.length)];
}
return res;
}
删除数组里指定下标的元素
删除指定下标-返回删除后的数组 与splice()相似-返回删除的数组
Array.prototype.delete = function (delIndex) {
var temArray = [];
for (var i = 0; i < this.length; i++) {
if (i != delIndex) {
temArray.push(this[i]);
}
}
return temArray;
};
点击切换函数
function switchTab(btn) {
for (let i = 0; i < btn.length; i++) {
btn[i].index = i;
btn[i].onclick = function () {
for (let j = 0; j < btn.length; j++) {
btn[j].classList.remove("isCheck")
btn[this.index].classList.add("isCheck");
}
}
}
}
js map 格式转化为对象
function _strMapToObj(strMap){
let obj= Object.create(null);
for (let[k,v] of strMap) {
obj[k] = v;
}
return obj;
}
时间戳转时间
function timestampToTime(timestamp) {
var date = new Date(timestamp * 1000);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
var Y = date.getFullYear() + '-';
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
var D = date.getDate() + ' ';
var h = date.getHours() + ':';
var m = date.getMinutes() + ':';
var s = date.getSeconds();
return Y + M + D + h + m + s;
}
一键复制
/*一键复制函数*/
function copyUrl(data) {
let url = data;
let oInput = document.createElement('input');
oInput.value = url;
document.body.appendChild(oInput);
oInput.select(); // 选择对象;
console.log(oInput.value)
document.execCommand("Copy"); // 执行浏览器复制命令
alert('复制成功')
oInput.remove()
}
初始化rem
function refreshRem() {
var docEl = doc.documentElement;
var width = docEl.getBoundingClientRect().width;
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
win.addEventListener('resize', refreshRem);
获取url参数
function getUrlParams(name) { // 不传name返回所有值,否则返回对应值
var url = window.location.search;
if (url.indexOf('?') == 1) { return false; }
url = url.substr(1);
url = url.split('&');
var name = name || '';
var nameres;
// 获取全部参数及其值
for(var i=0;i<url.length;i++) {
var info = url[i].split('=');
var obj = {};
obj[info[0]] = decodeURI(info[1]);
url[i] = obj;
}
// 如果传入一个参数名称,就匹配其值
if (name) {
for(var i=0;i<url.length;i++) {
for (const key in url[i]) {
if (key == name) {
nameres = url[i][key];
}
}
}
} else {
nameres = url;
}
// 返回结果
return nameres;
}
getParams(url) {
const index = url.indexOf('?') + 1
const params = url.slice(index).split('&')
const obj={}
for(let i =0;i<params.length;i++){
obj[params[i].split("=")[0]]=params[i].split("=")[1]
}
return obj;
}
计算坐标集中心点
calculateCenter(lnglatarr) {
let total = lnglatarr.length
let X = 0, Y = 0, Z = 0
lnglatarr.forEach((lnglat, index) => {
let lng = lnglat[0] * Math.PI / 180
let lat = lnglat[1].includes('#')?lnglat[2] * Math.PI / 180:lnglat[1] * Math.PI / 180
let x, y, z
x = Math.cos(lat) * Math.cos(lng)
y = Math.cos(lat) * Math.sin(lng)
z = Math.sin(lat)
X += x
Y += y
Z += z
})
X = X / total
Y = Y / total
Z = Z / total
let Lng = Math.atan2(Y, X)
let Hyp = Math.sqrt(X * X + Y * Y)
let Lat = Math.atan2(Z, Hyp)
return [Lng * 180 / Math.PI, Lat * 180 / Math.PI]
},
resetStyle
html{
/* 标准字体大小可以,在移动端使用的rem适配的话会动态改变。 */
font-size:14px;
/* 使用IE盒模型(个人取舍,我一般设置width是这是盒子的真实大小,包括padding和border) */
box-sizing: border-box;
}
html,body{
/* 在有些手机浏览器中点击一个链接或着可点击元素的时候,会出现一个半透明的灰色背景; */
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
/* 提升移动端滚动的体验效果 */
-webkit-overflow-scrolling: touch;
overflow-scrolling: touch;
/* 与浏览器窗口高度一致 */
height: 100%;
}
body{
/* 有些背景默认为浅灰色,所以统一设置为纯白 */
background: #fff;
/* 照着antd上面来的,在公司就别用微软雅黑了,不建议字体使用rem。 */
font:14px,-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Hiragino Sans GB','Microsoft YaHei',
'Helvetica Neue',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'
/* 使字体更加顺滑 */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* 去除浏览器默认的margin和padding, 自行删减一些不必要的标签 */
body,
p,
h1,
h2,
h3,
h4,
h5,
h6,
dl,
dd,
ul,
ol,
th,
td,
button,
figure,
input,
textarea,
form,
pre,
blockquote,
figure{
margin: 0;
padding: 0;
}
a{
/* 小手 */
cursor: pointer;
/* 取消超链接的默认下划线 */
text-decoration:none;
/* antd里面还做了 , 看你团队需不需要这样的风格 */
transition: color 0.3s ease;
}
ol,
ul{
/* 去除自带的ugly样式。 */
list-style:none
}
/* 这些节点部分属性没有继承父节点样式,所有继承一下,并取消outline,外轮廓的效果 */
a,
h1,
h2,
h3,
h4,
h5,
h6,
input,
select,
button,
textarea {
font-family: inherit;
font-size: inherit;
font-weight: inherit;
font-style: inherit;
line-height: inherit;
color: inherit;
outline: none;
}
button,
input[type='submit'],
input[type='button'] {
/* 可点击小手 */
cursor: pointer;
}
/* 取消部分浏览器数字输入控件的操作按钮 apperance可以改变控件的外观。 */
input[type='number'] {
-moz-appearance: textfield;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
margin: 0;
-webkit-appearance: none;
}
/**
* 删除Firefox中的内边框和填充。
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* 让html5中的hidden在IE10中正确显示
*/
[hidden] {
display: none;
}
template {
/* 有些浏览器会显示template 不过template标签用的也少,自行取舍。 */
display: none;
}
移动端css reset
@charset "utf-8";
/* 禁用iPhone中Safari的字号自动调整 */
html {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
/* 去除iPhone中默认的input样式 */
input[type="submit"],
input[type="reset"],
input[type="button"],
input{-webkit-appearance:none; resize: none;}
/* 取消链接高亮 */
body,div,ul,li,ol,h1,h2,h3,h4,h5,h6,input,textarea,select,p,dl,dt,dd,a,img,button,form,table,th,tr,td,tbody,article,
aside, details,figcaption,figure,footer,header,hgroup, menu,nav,section{ -webkit-tap-highlight-color:rgba(0, 0, 0, 0); }
/* 设置HTML5元素为块 */
article, aside, details,figcaption,figure,footer,header,hgroup, menu,nav,section {
display: block;
}
/* 图片自适应 */
img {
max-width: 100%;
height: auto;
width:auto\9; /* ie8 */
-ms-interpolation-mode:bicubic;/*为了照顾ie图片缩放失真*/
}
/* 初始化 */
body,div,ul,li,ol,h1,h2,h3,h4,h5,h6,input,textarea,select,p,dl,dt,dd,a,img,button,form,table,th,tr,td,tbody,article,
aside, details,figcaption,figure,footer,header,hgroup, menu,nav,section{margin:0; padding:0; border:none;box-sizing: border-box;}
body{font: normal 14px/1.5 Tahoma,"Lucida Grande",Verdana,"Microsoft Yahei",STXihei,hei;}
em,i{font-style:normal;}
strong{font-weight: normal;}
.clearfix:after{content:""; display:block; visibility:hidden; height:0; clear:both;}
.clearfix{zoom:1;}
a{text-decoration:none; color:#969696; font-family: '宋体',Microsoft YaHei,Tahoma,Arial,sans-serif;}
a:hover{color:#fff; text-decoration:none;}
ul,ol{list-style:none;}
h1, h2, h3, h4, h5, h6{ font-size:100%; font-family: Microsoft YaHei;}
img{border: none;}