如何将px转换为rem —— CSS单位转换详解
在前端开发中,我们常常面临响应式布局、字体适配和流式设计的挑战。传统的 px 单位虽然直观,但在多终端设备上使用时往往缺乏灵活性。为了解决这个问题,我们引入了 rem 单位,它基于根元素字体大小,能实现更灵活的布局;同时,我们也会结合 vw 单位来打造真正的流式设计,确保页面在不同屏幕下都能保持理想比例。 下面会先把 px -> rem 的换算讲清楚,再补两种常见工程化落地方式(Sass 函数 / PostCSS 插件),最后聊聊 vw 在流式布局里怎么用。 先说我自己的经验:别纠结“哪种单位最先进”,关键看你想解决什么问题——是做一套能跟着根字号整体缩放的设计(rem),还是希望尺寸跟视口宽度直接绑定(vw)。很多项目最后都是混用:字体/间距用 rem,容器宽度/大块区域用 vw。 理解 px、rem 与 vw 单位px – 像素 绝对单位:px 表示像素,是屏幕上最小的显示单位,通常不受用户设置字体大小的影响。 局限性:使用 px 时,页面在不同设备和用户缩放设置下可能显示不协调。 rem – 根 em 相对单位:rem 是相对于根元...
循环渲染中为何不建议用 index 做 key?
key 这个东西,你可能一开始只是为了消掉 React 的 warning 才加上去的。 但它其实会直接影响“列表更新时组件怎么复用”。用对了,你的输入框不会串行、展开态不会乱跳;用错了(尤其是用 index),有些 bug 会特别诡异:看起来像状态乱了,但其实是组件被 React 复用错了。 key 的作用1. 唯一标识每个列表项当你通过循环渲染一个列表时,每个列表项都需要一个独一无二的标识符,这就是 key 的作用。通过 key,框架能够准确地识别出每个元素,确定它们在数据更新时的变化。 例如,在 React 中,key 用于帮助虚拟 DOM 快速判断哪些元素发生了改变、哪些需要重新渲染或移除,从而提高页面更新的性能。 2. 保持组件状态使用正确的 key,可以确保在列表项发生增删或重新排序时,各个组件的内部状态能够正确地保留和复用。例如,如果你有一个表单组件列表,使用唯一的 key 能保证当用户在一个输入框中输入内容后,列表重新排序时,输入框中的数据不会错误地传递到其他组件上。 为什么不推荐使用 index 作为 key?1. 列表项顺序不稳定当列表项的顺序发生变化时...
同一链接如何PC、手机展示两套应用
在实际项目中,为了兼容多终端体验,我们常常希望通过同一个链接来为不同设备提供不同版本的页面。例如,在 PC 端展示完整的 Web 应用,而在手机端展示轻量化、优化的 H5 应用。如何实现这一目标? 我习惯先问一句:你想要的是“同一套应用做响应式”,还是“PC 和 H5 完全两套应用/两套路由”?前者成本更低,后者隔离更彻底,但工程复杂度也更高。 下面按常见落地方式拆开说: 服务端用户代理检测重定向 客户端响应式加载或动态模块切换 服务端检测用户代理原理通过服务器检测 HTTP 请求头中的 User-Agent,根据设备类型选择性地返回不同版本的页面。这样,同一个 URL 在 PC 和手机访问时,会由服务器根据检测结果决定返回哪个 HTML 模板。 示例(Node.js + Express)下面是一个简单的示例,通过 Express 中间件检测 User-Agent 并重定向到不同页面。 123456789101112131415161718const express = require('express');const app = exp...
如何减少项目中的if-else结构
先澄清一句:if-else 不是不能写,很多时候它反而最直观。 真正让人崩溃的是那种“套娃式”的判断:一个函数里几十个分支、嵌套三四层,改一个条件要担心连锁反应,测试也不好补。 下面这些方法的目标不是“消灭 if-else”,而是把复杂度压下去:让分支更扁平、让扩展更便宜、让代码读起来不费劲。 为什么要减少 if-else? 降低代码复杂度:过多的 if-else 分支会使代码阅读困难,增加理解成本。 提高可维护性:业务逻辑变化时,嵌套过深的判断难以定位和修改。 增强扩展性:模块化和面向对象的设计模式能够更轻松地扩展和复用代码。 便于测试:分支逻辑过多时,编写全面的测试用例变得繁琐,容易遗漏边界情况。 常见解决方案1. 使用策略模式策略模式将一系列算法封装为独立的策略对象,并通过上下文类动态选择执行。这样可以将 if-else 判断分散到不同的策略中。 示例代码: 1234567891011121314151617181920// 定义策略函数const strategies = { add: (a, b) => a + b, subtract: (a,...
JavaScript 作用域和闭包
这篇我不打算堆概念,直接用一组小例子把下面几件事串起来(看懂代码基本就懂了): 变量提升 this 的使用场景 作用域 闭包的应用 文章最后还有一个经典小题,用来检查你是不是真的理解了闭包/作用域链。 变量提升首先我们要知道,js的执行顺序是由上到下的,但这个顺序,并不完全取决于你,因为js中存在变量的声明提升。 这里比较简单,直接上代码 123456789console.log(a) //undefinedvar a = 100fn('zhangsan')function fn(name){ age = 20 console.log(name, age) //zhangsan 20 var age} 结果 打印a的时候,a并没有声明,为什么不报错,而是打印undefined。 执行fn的时候fn并没有声明,为什么fn的语句会执行? 这就是变量的声明提升,代码虽然写成这样,但其实执行顺序是这样的。 1234567891011var afunction fn(name){ age = 2...
JavaScript 的类与继承
类的声明与实例化类的声明一般有两种方式 1234567891011//类的声明var Animal = function () { this.name = 'Animal';};//ES6中类的声明class Animal2 { constructor () { this.name = 'Animal2'; }} 实例化就比较简单,直接用 new 运算符 123new Animal()new Animal2() 上面第一行应该是 new Animal()(手滑拼错经常发生),概念上就是“用构造函数创建实例”。 这些比较简单,简单介绍一下就可以了。接下来,介绍本文的重点内容,继承。 如何实现继承实现继承的方式主要有两种: 第一种借助构造函数实现继承 先看个了例子 12345678function Parent1 () { this.name = 'parent1';}function Child1 (...
详谈 JavaScript 原型链
创建对象的方法原型链这块最容易把人绕晕,我建议从“对象是怎么来的”开始看:常见创建对象方式大概三种。 代码: 123456789101112131415<script type="text/javascript"> // 第一种方式:字面量 var o1 = {name: 'o1'} var o2 = new Object({name: 'o2'}) // 第二种方式:构造函数 var M = function (name) { this.name = name; } var o3 = new M('o3') // 第三种方式:Object.create var p = {name: 'p'} var o4 = Object.create(p) console.log(o1) console.log(o2) console.log(o3) console.log(...
三栏布局的五种解决方案及优缺点
问题假设高度已知,请写出三栏布局,左栏、右栏宽度300px,中间宽度自适应。 三栏布局本身不难,难的是“你能不能说清楚为什么这么写、有什么坑、还有哪些替代方案”。 面试爱问这题也很现实:它覆盖了 float/定位/flex/table/grid 这些布局心智。只会写一种当然也能做出来页面,但遇到兼容性、内容高度变化、或者要做响应式的时候,就会暴露短板。 样式下面是5种三栏布局的方法。在写布局代码之前,先写两段公共的样式,此段写在头部。 12345678910<style media="screen"> html *{ padding: 0; margin: 0; } .layout article div{ min-height: 100px; } </style> 1. 浮动布局1234567891011121314151617181920212223242526...
深入理解 CSS 盒模型
前言盒模型这题看起来“太基础”,但真要讲清楚,细节不少:box-sizing 影响宽高怎么算;margin 为啥会重叠;BFC 又是怎么一把解决一类布局问题的。 下面按几个常见问题把它捋一遍: 基本概念:标准模型 和IE模型 CSS如何设置这两种模型 JS如何设置获取盒模型对应的宽和高 实例题(根据盒模型解释边距重叠) BFC(边距重叠解决方案) 基本概念盒模型的组成大家肯定都懂,由里向外content,padding,border,margin. 盒模型是有两种标准的,一个是标准模型,一个是IE模型。 从上面两图不难看出在标准模型中,盒模型的宽高只是内容(content)的宽高, 而在IE模型中盒模型的宽高是内容(content)+填充(padding)+边框(border)的总宽高。 css如何设置两种模型这里用到了CSS3 的属性 box-sizing 12345/* 标准模型 */box-sizing: content-box;/* IE 模型 */box-sizing: border-box; JS获取宽高通过JS获取盒模型对应的宽和高,有以下几种方法: 为...
深入解析 Cookie、sessionStorage 和 localStorage 的区别
Cookie、sessionStorage、localStorage 这三个东西,日常开发里几乎天天见:登录态、埋点、用户偏好、临时缓存…… 它们的区别不只是“大小不一样”,更关键的是:生命周期、是否随请求携带、以及安全边界。选错了要么拖慢请求,要么埋下安全坑。 1. 容量限制与数据格式 存储方式 容量限制 数据格式 Cookie 4KB 只能存储字符串 sessionStorage 约 5MB 只能存储字符串(可转换为 JSON) localStorage 约 5MB 只能存储字符串(可转换为 JSON) 补一句:虽然 sessionStorage/localStorage 只能存字符串,但可以用 JSON.stringify() 存对象,取出时 JSON.parse() 还原。 1234const user = { name: "张三", age: 25 };localStorage.setItem("user", JSON.stringify(user));const store...
