在一个网页中一个Id可以用很多次
HTML规范里写得很清楚,id在同一个页面中必须唯一。页中用多但你要真去翻那些老站点的个网个源码,尤其是页中用多十年前用jQuery写的前台页面,能找到一堆id="main"、个网个id="content"在不同模块里反复出现。页中用多没人管,个网个浏览器也不报错,页中用多页面照样跑得欢。个网个
为什么?页中用多因为document.getElementById只返回第一个匹配的节点。你要是个网个用querySelectorAll,它根本不关心id重复不重复,页中用多全给你捞出来。个网个所以“一个id只能用一次”更像是页中用多一个给人类看的纪律,而不是个网个浏览器强制的法律。你违反了,它顶多在心里翻个白眼,然后默默忽略后面的同名id。
我去年接手过一个内部管理系统,模板是外包写的。搜索功能、筛选栏、分页控件,每个组件里都硬塞了一个id="resetBtn"。页面渲染出来,浏览器控制台干干净净,连个警告都没有。但问题出在事件绑定上——外包用document.getElementById('resetBtn').addEventListener,结果只有第一个重置按钮能触发,其他几个模块的重置功能全成了摆设。
实际调试的时候更搞笑。我打开DevTools,在Console里敲document.getElementById('resetBtn'),它总是返回第一个。我以为是代码逻辑写岔了,排查了半小时,最后用document.querySelectorAll('[id="resetBtn"]')一查,好家伙,页面上有7个同名id。
这事儿给我的教训是:id重复不报错,不代表你可以随便用。它带来的问题非常隐蔽,尤其在现代前端框架普及之前,老代码里到处都是这种坑。你说框架就不踩雷?Vue或React里,如果你用ref而不是id,倒没这问题。但你要是混着写,比如某个子组件里用了id="modal",父组件又有一个id="modal",那document.getElementById永远只认第一个——而且这个“第一个”取决于DOM树中的位置,跟组件嵌套逻辑无关。
所以我的态度很明确:规范说唯一,你就该当回事。但如果你真碰上了重复id的烂摊子,也别慌——用querySelectorAll配合class或data-*属性去定位,比纠结id要靠谱得多。我后来把那个系统的所有resetBtn全改成了class="reset-btn",再配合事件委托,问题直接消失。
顺带说一句,HTML5时代大家都爱用语义化标签,id的地位反而下降了。很多场景下,class或自定义属性比id更灵活,也更适合复用。但你要是真想在同一个页面里用同一个id两次,浏览器不会拦你,规范书也不会从屏幕里跳出来打你手——它顶多让你的代码在未来的某次维护中,变成一个让人抓狂的谜题。
反正我是改过自新了。你呢?
本文地址:http://www.79wt.cn/news/1274c9099782.html
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。