• 前端 BUG 总结


    文章目录

    • CSS 样式
        • 1、Chrome 89 版本期不再支持 `/deep/`,请勿使用嵌套 `/deep/`
        • 2、圆角按钮 button 点击后出现矩形框线
        • 3、怪异模式
        • 4、`border` 1 像素在手机上显示问题
        • 5、文本溢出问题
    • JavaScript 脚本
        • 1、移动端点击穿透
        • 2、使用`parseInt`时必须补全第二个参数 `radix`
        • 3、有关`Input`标签`capture`属性
        • 4、`setTimeout/setInterval`函数第一个参数误用字符串
        • 5、在为变量重置`get`、`valueOf`、`toString`时请谨慎
        • 7、`null`是不是`object`
        • 8、诡异的参数


    CSS 样式

    1、Chrome 89 版本期不再支持 /deep/,请勿使用嵌套 /deep/

    发现使用 chrome 最新版(v89),有个别样式出现了问题,排查定位后发现是有些错误地嵌套使用/deep/,在 v88 下是没问题的,但在 v89 下就出现了问题,不再生效。我们使用 VUE 框架,ElementUI 组件库,Dialog 控件样式(SCSS)写成了:

    .my-dialog {
      /deep/ .el-dialog {
        /deep/ .el-dialog__body {
          height: 600px;
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意:嵌套使用/deep/是错误的,但在之前的版本没有发现问题便没发现

    chromestatus chromestatu里有:

    The /deep/ combinator was a part of Shadow DOM v0, which has been deprecated and removed. Starting in M63, the /deep/ combinator was treated as a no-op, equivalent to a space “ “ combinator. As the code for all of Shadow DOM v0 was removed completely in M89, /deep/ will now throw exceptions in some JS operations, such as querySelectorAll. Simply replace it with “ “ to get pre-M89 behavior back.

    翻译过来的意思是,在 89 之前,chrome 浏览器会将/deep/ 当作空格字符串来处理,后面就完整删除 Shadow DOM v0 的内容了。


    2、圆角按钮 button 点击后出现矩形框线

    解决办法:

    outline: none;
    
    • 1

    3、怪异模式

    没有书写时会触发怪异解析现象。

    解决办法: 请完整书写


    4、border 1 像素在手机上显示问题

    原因: 1px在手机上是使用2dp进行渲染,换成 border: 0.5 是不行的!

    解决办法: 通过给元素的beforeafter伪类设置border或者height,然后让伪类利用 css3 的transformscaleY(0.5)缩放 0.5 像素


    5、文本溢出问题

    • 单行文本溢出
    overflow: hidden;
    white-wrap: nowrap;
    text-overflow: ellipsis;
    
    • 1
    • 2
    • 3
    • 多行文本溢出
    overflow: hidden;
    word-break: break-all;
    text-overflow: ellipsis;
    -webkit-box-orient: vertical;
    /* 3表示第四行溢出 */
    -webkit-line-clamp: 3;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    JavaScript 脚本

    1、移动端点击穿透

    背景: 当点击绝对定位元素的时候,下面的元素虽然被遮盖,但也被触发了。

    原因: touchstart 早于 touchend 早于 click

    解决办法:

    • (1)尽量都使用 touch 事件来替换 click 事件。例如用 touchend 事件(推荐)。
    • (2)用 fastclick
    • (3)用 preventDefault 阻止 a 标签的 click
    • (4)延迟一定的时间(300ms+)来处理事件 (不推荐)
    • (5)以上一般都能解决,实在不行就换成 click 事件。

    2、使用parseInt时必须补全第二个参数 radix

    参考文档:parseInt


    3、有关Input标签capture属性

    HTML5 官方文档解释:capture 属性用于调用设备的摄像头或麦克风。

    accept="audio/*"或者accept="video/*"capture只有以下两种值:

    描述
    user调用面向用户的摄像头(前置摄像头)和/或麦克风
    environment调用朝外的摄像头(后置摄像头)和/或麦克风

    iOS 最遵守遵守 HTML5 规范,其次是 X5 内核,安卓的 webview 基本忽略了 capture

    理想情况下应该按照如下开发 webview:

    • (1). 当 accept="image/*"时,capture="user"调用前置照相机,capture="其他值",调用后置照相机
    • (2). 当 accept="video/\*"时,capture="user"调用前置录像机,capture="其他值",调用后置录像机
    • (3). 当 accept="image/_,video/_"capture="user"调用前置摄像头,capture="其他值",调用后置摄像头,默认照相,可切换录像
    • (4). 当 accept="audio/*"时,capture="放空或者任意值",调用录音机
    • (5). 当 input 没有 capture 时,根据 accppt 类型给出文件夹选项以及摄像头或者录音机选项
    • (6). input 含有 multiple 时访问文件夹可勾选多文件,调用系统摄像头或者录音机都只是单文件
    • (7). 无 multiple 时都只能单文件

    参考文档:

    • https://w3c.github.io/html-media-capture/
    • https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/capture
    • https://caniuse.com/html-media-capture
    • https://w3c.github.io/html-media-capture/#examples
    • https://stackoverflow.com/questions/21523544/html-file-input-control-with-capture-and-accept-attributes-works-wrong

    4、setTimeout/setInterval函数第一个参数误用字符串

    原因: 如果你将一个字符串作为setTimeout/setTimeInterval,它会被传给函数构造函数并构建一个新的函数。该操作流程很慢而且低效,并导致 bug 出现。

    解决办法: 传入函数作为参数

    function loop() {
      /* skip */
    }
    setInterval(loop, 1000);
    
    • 1
    • 2
    • 3
    • 4

    5、在为变量重置getvalueOftoString时请谨慎

    原因: 考虑以下这些情况:

    • v === 1 && v === 2,如果重置vget 方法,这种情况将成立
    let i = 1;
    Object.defineProperty(window, 'v', {
      get() {
        return i++;
      }
    });
    
    console.log(v === 1 && v === 2); // true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • v == 1 && v == 2, 如果重置vvalueOf方法,这种情况将成立
    let v = {
      i: 0,
      valueOf() {
        return (this.i += 1);
      }
    };
    console.log(v == 1 && v == 2); // true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    7、null是不是object

    console.log(typeof null); // object
    console.log(null instanceof Object); // false
    console.log(Object.prototype.toString.call(null)); // [object Null]
    
    • 1
    • 2
    • 3

    8、诡异的参数

    function hello(name) {
      console.log(arguments[0]); // vicky
      name = 'world';
      return 'Hello, ' + arguments[0] + '!';
    }
    
    console.log(hello('Rodey')); // Hello, world!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    原因: name形参并非是arguments类数组对象元素的引用。


  • 相关阅读:
    asp.net core mvc 之 依赖注入
    渗透测试工具(3)Burpsuite
    期权开户流程合集——期权开户的操作步骤
    Nginx之防盗链及高可用解读
    寄存器、缓存、内存(虚拟、物理地址)、DDR、RAM的关系
    训练模型时,wandb关闭问题。你以为加了一句 wandb = None 就能关闭了吗?
    Spring入门程序(二)
    tomcat下载安装及配置教程
    Vue 将响应式数据转为普通对象
    【C语言】—— 动态内存管理
  • 原文地址:https://blog.csdn.net/weiCong_Ling/article/details/134342425