纯CSS媒体查询可解决90%导航布局切换,JavaScript仅需处理重置状态、加载数据等逻辑;matchMedia比window.innerWidth+resize更可靠,能同步CSS媒体状态并覆盖横竖屏、缩放等场景。

纯 CSS 媒体查询能解决 90% 的导航布局切换问题,JavaScript 只需在必须触发逻辑时介入——比如重置展开状态、加载差异化数据或上报设备类型。
为什么 window.innerWidth + resize 监听容易出错
直接读取 window.innerWidth 并在 resize 事件里做判断,看似简单,但会漏掉关键场景:横竖屏切换(iOS Safari)、系统缩放变化、PWA 窗口拖拽至分屏模式。这些操作不一定会触发 resize,但媒体查询状态已变。
- 用
window.innerWidth 判断“是否为移动端”,首次加载可能对,窗口拉宽后仍保持旧状态 -
resize频繁触发未节流,导致布局抖动或重复初始化 - 无法感知 CSS @media 实际生效与否(例如被父容器
display: none阻断)
matchMedia 是更可靠的媒体状态同步机制
matchMedia 返回的是一个实时反映 CSS 媒体查询结果的对象,它不依赖像素值,而是复用浏览器渲染引擎的判断逻辑,和样式表完全同步。
- 写法统一:
const mql = window.matchMedia("(max-width: 767px)"),和 CSS 中写的断点完全一致 - 必须手动调用一次回调函数,否则页面加载时不执行初始逻辑:
handleNavState(mql) - IE11 不支持
addEventListener("change", ...),要用mql.addListener(handleNavState)回退 - 多个断点建议拆成独立实例,避免写成
"(min-width: 768px) and (max-width: 1023px)"—— 条件耦合会让状态切换不可预测
导航栏展开状态必须靠 class 控制,不能改内联样式
用 element.style.display = "block" 或 jQuery 的 .show() 会覆盖媒体查询的样式优先级,导致屏幕变宽后菜单卡在“展开”态。
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
- 正确做法:只操作类名,如
nav.classList.toggle("open") - 让
.nav.open ul的display: block仅在@media (max-width: 767px)内生效 - 这样即使 JS 忘记清理
.open类,在桌面尺寸下它也毫无作用 - 配合
matchMedia在断点切换时自动清理:进入大屏时调用nav.classList.remove("open")
链接参数按屏幕尺寸动态生成的两种安全方式
如果导航链接需要传不同参数(如 /report?range=30d vs /report?range=90d),不要在 JS 里拼 URL 字符串后直接赋给 href —— 这会导致 SEO 损失和 SSR 不一致。
- 推荐方案:纯 CSS,用
,再通过媒体查询控制哪个href生效(需配合pointer-events: none和伪元素 hack,较复杂但零 JS) - 可行方案:服务端根据
User-Agent或客户端matchMedia结果预设一个全局变量(如window.__SCREEN_TYPE = "mobile"),JS 初始化时读取并重写href,但需确保首屏 HTML 已含 fallback 链接 - 绝对避免:在
resize里反复修改所有的href,会造成重排+ history.pushState 干扰
真正难的不是“怎么切”,而是“切完之后状态要不要保留、保留多久、由谁负责清理”。很多 bug 都源于假设 JS 状态和 CSS 状态天然一致——它们并不一致,必须显式桥接。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










