Excel 小数计算精度问题

背景 在做金额、折扣、税率、比例这类计算时,我们经常会默认认为: 1 2 3 0.1 + 0.2 - 0.3 = 0 19.99 * 100 = 1999 ROUND(1.255, 2) = 1.26 但是在 Excel 里,这些表达式并不总是符合“十进制心智模型”。问题通常不是 Excel 把公式写错了,而是 Excel 和大多数编程语言一样,底层使用有限精度的二进制浮点数保存和计算数字。 微软文档里也明确提到,Excel 围绕 IEEE 754 浮点规范设计,部分数字和公式会受到舍入或数据截断影响;Excel 的数字精度也限制在 15 位有效数字左右。 这篇文章记录一次复现:
阅读更多

iOS Safari 多个 input 调用 setSelectionRange 导致焦点抢占的问题

背景 在移动端 H5 表单里,经常会遇到这样的需求:用户输入手机号、银行卡号、验证码、金额等内容时,前端需要格式化输入值,同时把光标恢复到合适的位置。 常见做法是调用 input.setSelectionRange(start, end) 来恢复选区或者光标位置。 这个 API 在大多数桌面浏览器上表现很稳定,但在 iOS Safari 上需要特别小心。一次排查中发现:如果页面上有多个 input,并且代码批量对这些输入框调用 setSelectionRange,在 iOS 16.4 Safari 上可能会出现焦点被后面的输入框抢走的问题。 最终现象是: 1. 当前并不想聚焦某个输入
阅读更多

自定义pre-commit脚本

需求背景 QNSolutions_Web 是一个多项目集成的 repo,front 下是多个项目,而 solution 下是一个 monorepo。 现需要实现当某个项目中有文件变更 commit 时,只对该项目进行 lint-staged 操作,而不是对整个 repo 进行 lint-staged 操作。 Repo 结构如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 . ├── portal │ └── front │ ├── portal-solution │ ├── portal-solution-admin
阅读更多

记一次monorepo项目由yarn workspace+lerna迁移至pnpm

首先来说一下 npm、yarn、pnpm 的区别 npm vs yarn vs pnpm npm 在 npm3 之前,安装依赖包时采用简单的递归安装方法。而在npm3及之后,采用的是模块扁平化安装。 yarn(摘自https://juejin.cn/post/6964006257715838984) yarn 出生之后,解决了历史上 npm 的某些不足,比如 npm 缺乏对于依赖的完整性和一致性保障,以及 npm 安装速度过慢的问题等,尽管 npm 发展至今,已经在很多方面向 yarn 看齐,但 yarn 的安装理念仍然需要我们关注。 yarn 提出的安装理念很好的解决了当时 npm 的依
阅读更多

document.querySelector() 无法使用以数字开头的 id

一次开发中使用 document.querySelector 发现会报错 使用姿势如下: 1 document.querySelector(`#{xxx}`) xxx 为服务端返回的 uuid 变量,经排查发现当 xxx 是数字开头的时候就会报错。 原因如下: document.querySelector(selectors) 中 selectors 规范是: 包含一个或多个要匹配的选择器的 DOM 字符串 DOMString。 该字符串必须是有效的CSS选择器字符串;如果不是,则引发SYNTAX_ERR异常。请参阅使用选择器定位DOM元素以获取有关选择器以及如何管理它们的更
阅读更多

关于 Chrome 音视频自动播放的问题

在 Chrome 音视频播放的时候,play() 返回的是一个 promise,当播放失败的时候一般会显示一个按钮让用户手动进行播放。 但是在浏览其他大型视频网站的时候,会发现他们的网站貌似没出现过该问题。于是去查阅了相关资料。 其实最主要查看 https://developer.chrome.com/blog/autoplay 即可得到答案。 总结就是 Chrome 有个自动播放的策略。 Chrome 中的自动播放策略 改善用户体验,减少安装广告拦截器的动机,并减少数据消耗 Chrome 66 中针对音频和视频元素推出的自动播放策略有效地阻止了 Chrome 中大约一半不需要的媒体
阅读更多

记一次数据过大导致safari渲染卡死

在一次项目开发中,Chrome 调试移动端项目没问题,但是在移动端的 safari 下,会导致 safari 卡死。 后经排查,是将 base64 的数据直接渲染到页面而导致的, 所以解决办法就是过滤掉 base64 的数据渲染。 说一下为什么要把 base64 渲染到页面,因为该项目是作为一个介绍 sdk 的使用姿势,然后展示数据。
阅读更多

在网站搭建初期给z-index 分层规范

一般来说前端架构师在网站搭建初期就要给 z index 分层: * 0+ 用于普通内容 * 16+ 用于导航 * 32+ 用于导航菜单 * 64+ 用于 tooltip * 128+ 用于 popover * 256+ 用于对话框 * 1024+ 用于 loading 类似这样
阅读更多

Chrome 中 post 请求体过大导请求体和响应体无法正常展示

背景 Chrome 版本: 版本 95.0.4638.54(正式版本) (arm64) 机型如下: * macOS Big Sur * MacBook Pro (13-inch, M1, 2020) * 芯片 Apple M1 * 内存 16GB 一次开发中,一个 post 请求的请求体含有多个 base64 数据,在 Chrome 中请求后遇到如下问题: * http 响应 500 (服务端错误,忽略) * 请求体消失了 * 响应体无法显示 在服务端 500 问题修复之后,起初以为请求体和响应体不显示的问题会导致请求体丢失导致无法正常响应,可是发现只是 Chrome
阅读更多

Vite 无法通过 import xxx from 'path/xxx.umd.js' 的方式正常引入 UMD 模块使用

背景 首先打包出一个 umd 模块的 js 库,这里用 add.umd.js 来表示这个库吧。 然后测试发现: * 在 create-react-app 的项目中通过 import add from 'path/add.umd.js' 方式可以正常引入并使用 * 在 Vite 的项目中(个人测试是通过 yarn create vite 选择 react-ts 模板生成) import add from 'path/add.umd.js' 无法正常导入并使用。然而通过 import 'path/add.umd.js' 却可以正常导入,使用姿势大致如下所示:
阅读更多