前端知识点总结

363 阅读4分钟

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: '业务错误。',
};