script 有三种常见加载模式
- 默认加载:会阻塞 DOM 构建
- defer 加载:下载照旧,但执行延后
- 给 script 标签添加了 defer 属性后,脚本不会阻塞 DOM 树的构建,会先下载资源,然后等待到在 DOMContentLoaded 事件前执行
- async:下载完就立即执行,适合没有依赖的脚本
此外还有动态加载的脚本的情况,这种脚本默认为 async 加载形式,可通过将 async 属性设置为 false 来解除,让脚本顺序执行(这就是为什么要放到 html body 底部的原因)
局部滚动条置顶
document?.getElementById('areaType')?.scrollTo(0, 0);
canvas 实现图片压缩
const compressImg = (file: any) => {
const reader = new FileReader();
// readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成DONE,并触发 loadend (en-US) 事件,
// 同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。
reader.readAsDataURL(file);
return new Promise((resolve) => {
reader.onload = () => {
const img: any = document.createElement('img');
img.src = reader.result;
img.onload = () => {
// 图片的宽高
const w = img.width;
const h = img.height;
const canvas = document.createElement('canvas');
// canvas对图片进行裁剪,这里设置为图片的原始尺寸
canvas.width = w;
canvas.height = h;
const ctx: any = canvas.getContext('2d');
// canvas中,png转jpg会变黑底,所以先给canvas铺一张白底
ctx.fillStyle = '#fff';
// fillRect()方法绘制一个填充了内容的矩形,这个矩形的开始点(左上点)在
// (x, y) ,它的宽度和高度分别由width 和 height 确定,填充样式由当前的fillStyle 决定。
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制图像
ctx.drawImage(img, 0, 0, w, h);
// canvas转图片达到图片压缩效果
// 返回一个包含图片展示的 data URI base64 在指定图片格式为 image/jpeg 或 image/webp的情况下,
// 可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
const dataUrl = canvas.toDataURL('image/jpeg', 0.1);
// base64格式文件转成Blob文件格式
const blobFile = dataURLtoBlob(dataUrl);
// 拿到这个blobFile文件就可以上传给服务端
resolve(blobFile);
console.log('压缩前的file----------', file.size / 1024 / 1024);
console.log('压缩后的file----------', blobFile.size / 1024 / 1024);
};
};
});
};
// canvas生成的格式为base64,需要进行转化
const dataURLtoBlob = (dataurl: any) => {
const arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = window.atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
};
错误处理
// ErrorEvent类型的event包含有关事件和错误的所有信息。
window.addEventListener('error', function(event) {
// 处理错误
const { message, stack } = event.error
const trackData = {
type_name: 'errorListener',
message,
data_string: stack
}
})
// 为了防止有漏掉的 Promise 异常,监听Uncaught Promise Error
window.addEventListener('unhandledrejection', function(e) {
// 处理错误
const { message, stack } = e.reason
const trackData = {
type_name: 'unhandledrejection',
message,
data_string: stack
}
})
移动端安全区域
padding-top: env(safe-area-inset-top);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
padding-bottom: env(safe-area-inset-bottom);
}
解决键盘弹出后挡表单的问题
window.addEventListener('resize', ()=> {
const tagName = document.activeElement.tagName;
if(tagName === 'INPUT' ||tagName === 'TEXTAREA') {
window.setTimeout(()=> {
if('scrollIntoView' in document.activeElement) {
document.activeElement.scrollIntoView();
} else {
document.activeElement.scrollIntoViewIfNeeded();
}
}, 0);
}
});
});
常见的ZIP 命令
-c 将解压缩的结果显示到屏幕上,并对字符做适当的转换。
-l 显示压缩文件内所包含的文件。
-v 执行是时显示详细的信息。
-a 对文本文件进行必要的字符转换。
-b 不要对文本文件进行字符转换。
-C 压缩文件中的文件名称区分大小写。
-j 不处理压缩文件中原有的目录路径。
-L 将压缩文件中的全部文件名改为小写。
-n 解压缩时不要覆盖原有的文件。
-o 不必先询问用户,unzip执行后覆盖原有文件。
-P<密码> 使用zip的密码选项。
-q 执行时不显示任何信息。
-s 将文件名中的空白字符转换为底线字符。
-V 保留VMS的文件版本信息。
-X 解压缩时同时回存文件原来的UID/GID
shell 打包文件
#!/bin/bash
echo "参数:" $1
if [ $1 ]; then
rm -rf dist
rm -rf dist.zip
npm run $1
zip -qr dist.zip ./dist
else
echo '参数:不存在,请输入参数,参数命令必填
测试:sh build.sh build_sit
线上:sh build.sh build'
fi
常用的正则表达式
const desc = '112211'?.replace(new RegExp(11, 'g'), `你好世界`)====>你好世界22你好世界
<span className={style.remark} dangerouslySetInnerHTML={{ __html: desc }} />
动态replace 替换后端返回的数据,不能用replaceAll(兼容性不是很好) 需要注意
=================================================================================
value.replace(/\s+/g, ''); ====> 去除空格
携带 cookie 时 不能写 * ===>不支持
- 设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin", "http://127.0.0.1:8080");
- 允许的header类型
res.header("Access-Control-Allow-Credentials", "true");
- 跨域允许的请求方式
res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
res.header("Access-Control-Allow-Headers",xxxx");
手机端 vconsole 调试工具
* vConsole v3.0.0 (https://github.com/Tencent/vConsole)
全量引入即可,不能说是在webpack 中 require 引入,低版本手机会直接白屏
nginx 配置的缓存配置
if ($request_filename ~* .*\.(?:htm|html)$) {
add_header Cache-Control "no-store, no-cache";
}
if ($request_filename ~* .*\.(?:js|css)$) {
expires 30d;
}
正则匹配中文
(.[\u4E00-\u9FA5]+)|([\u4E00-\u9FA5]+.)
chrome 请求报错
- has been blocked by CORS policy: The request client is not a secure context and the resource is in more-private address space private(已被 CORS 策略阻止:请求客户端不是安全上下文,资源在更私人的地址空间中是私人的
- 原因
因为当前请求的地址是公网地址,然后请求的资源在内网地址,所以被 chrome 拦截
- 解决方法
在 chrome 中访问:
chrome://flags/#block-insecure-private-network-requests将其修改为disabled|| 将所有的地址全部修改为公网或者内网地址
CSS 属性
Text-align 是一个 CSS 属性,用于对文本内容在容器中的水平对齐方式进行控制。常见的属性值有以下几种:
- Left(默认值):将文本内容左对齐。
- Right:将文本内容右对齐。
- Center:将文本内容居中对齐。
- Justify:将文本内容两端对齐,行中的文本会在容器中均匀分布。
- Start:根据文本所在的文本方向,将文本内容左对齐(LTR 文本方向)或右对齐(RTL 文本方向)。
- End:根据文本所在的文本方向,将文本内容右对齐(LTR 文本方向)或左对齐(RTL 文本方向)。
掘金的头像旋转效果是咋做的 ?
.user-info-block .avatar[data-v-81cc69da]:hover {
transform:rotate(666turn);
transition-delay:1s;
transition-property:all;
transition-duration:59s;
transition-timing-function:cubic-bezier(.34, 0, .84, 1)
}
一些移动上去缓慢放大的图片效果
%0 {
transform:scaleX(1);
}
50% {
transform:scale3d(1.05,1.05,1.05);
}
100% {
transform:scaleX(1);
}
大屏幕可视化代码适配
const handleResize = (size: Size) => {
const { width } = size;
const baseScreenWidth = 1920 // 假设基准屏幕宽度为 1920px
const baseScreenHeight = 1080 // 假设基准屏幕高度为 1080px
const scaleX = width / baseScreenWidth
// 根据计算得到的缩放比例应用到可视化大屏幕组件上
// 例如,你可以通过设置样式来调整缩放比例:
const screenMonitoringContainer = document.querySelector('xxx') as HTMLElement
if (screenMonitoringContainer) {
screenMonitoringContainer.style.transform = `scale(${scaleX},${scaleX})`
screenMonitoringContainer.style.transformOrigin = '0 0';
}
}
zoom 适配方案
const handleWinAutoResize = () => {
let zoom: number = 1;
// 最小支持 1366分辨率
if (/webkit/i.test(navigator.userAgent.toLowerCase())) {
zoom = Math.max(window.screen.width / 1920, 0.7);
}
document.body.style.setProperty("--zoom", String(zoom));
document.body.style.setProperty("zoom", String(zoom));
};
handleWinAutoResize();
// 切换屏幕自适应
if ("onchange" in window.screen) {
(window.screen as any).onchange = () => handleWinAutoResize();
}
status code 映射
const codeMessage = {
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户没有权限(令牌、用户名、密码错误)。',
403: '用户得到授权,但是访问被禁止。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到。',
500: '服务器发生错误。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
510: '业务错误。',
};