为什么拥有多个具有相同id属性的HTML元素是不好的?

11

为什么在同一页上有多个具有相同id属性的HTML元素是不好的做法?我正在寻找一种方法向不熟悉HTML的人解释这一点。

我知道HTML规范要求id必须唯一,但这听起来并不是一个令人信服的原因。我为什么要关心别人在某些文档中编写了什么?

我能想到的主要原因是,具有相同id的多个元素可能会导致JavaScript函数(如document.getElementById)出现奇怪和未定义的行为。我也知道它可能会导致URL中的片段标识符出现意外的行为。还有其他任何让HTML新手感到有道理的原因吗?


现在的方式非常合理。虽然“class”可能会更改为类似于“style-class”,以使其更有意义。 - user744186
2
你应该关注某个文档中写了什么。如果没有定义、审核和接受的标准,我怀疑你是否有这样的地方来提出这个问题 :-) - andyb
哈!韦斯利把他的名字改成了 @mog。 - Ziggy
9个回答

13

根据您的问题,您已经知道w3c对此的解释:

id属性指定HTML元素的唯一标识符(id属性值必须在HTML文档中是唯一的)。

id属性可用于指向样式表中的样式。

id属性还可以由JavaScript(通过HTML DOM)用于更改具有特定id的HTML元素。

id的重点是它必须是唯一的。它用于标识元素(或任何东西:如果两个学生具有相同的学生ID,则学校将分崩离析)。这不像人名,不需要唯一。如果数组中的两个元素具有相同的索引,或者两个不同的实数相等...宇宙将会崩溃,这是其身份定义的一部分。

我认为你应该使用class来完成你想做的事情(ps:你想做什么?)。

希望能对您有所帮助!


我正在开发一个网站,有人在帮我放置多个具有相同id的元素,我正在尝试找出一种解释为什么这不是一个好主意的方法。 - Elias Zamaria
我尝试将相同的ID分配给多个元素,结果出现了一些略微古怪的行为,但据我所知,宇宙还没有崩溃。 - Elias Zamaria
以后您将无法再使用document.getElementByid了。这太荒谬了!这就像使用表格来格式化您的网站一样:当然,人们会这样做并且它起作用,但它是不可扩展的,而且这不是表格标签的用途(它是用于显示表格数据的)。您的同事需要明白,这些标准的目的是为了使互联网的不同部分协同工作。今天,您的网站不会因为有多个相同的ids而崩溃...但如果他不遵循标准,那么不能保证以后不会崩溃。明白了吗? - Ziggy

6

为什么我要关心别人在某个文档中写了什么?

你应该关心,因为如果你正在编写HTML,它将在由关心的人编写的浏览器中呈现。 W3C创建了规范,Google,Mozilla,Microsoft等公司都在遵循它,所以你也有兴趣遵循它。


4
除了显而易见的原因(它们应该是唯一的),您应该关心多个具有相同id的元素可能会破坏您的应用程序。
假设您有以下标记:
<p id="my_id">One</p>
<p id="my_id">Two</p>

CSS很宽容,这将使两个元素都变成红色:

#my_id { color:red; }

但是使用JavaScript,这样只会样式化第一个元素:

document.getElementById('my_id').style.color = 'red';

这只是一个简单的例子。当您使用JavaScript编写依赖于唯一id的任何内容时,整个应用程序可能会崩溃。每天都有人在这里发布问题,实际上出现了这种情况-由于开发人员使用了重复的id属性,某些关键功能已经损坏。


1
我看到这个问题在问题主体中已经得到了解决,但今天我至少读了5篇帖子,都在问为什么某些东西坏了(所有问题都通过修复重复的ID得到了解决)。我找不到一个“规范帖子”来明确地说:“不,你不能有重复的ID”。希望这能为教育努力增添一点动力。 - Wesley Murch
在我看来,这是对原问题的最佳答案:CSS和JavaScript的不同行为。使用JS的一个解决方案是,通过发出警告,将document.getElementById('my_id')替换为document.querySelectorAll('#my_id')[0],同时确保document.querySelectorAll('#my_id').length > 1。 - allez l'OM

2

因为如果您有多个具有相同ID的HTML元素,则它不再是标识符了,对吧?

为什么两个人不能拥有相同的社会安全号码?


他们可以。虽然通常被称为“身份盗窃”... :) - cHao
3
啊,在 HTML 中,它只是被称为“松散的(sloppy)”。 - JHolyhead

2
你基本上回答了这个问题。我认为只要一个元素不能通过id属性进行唯一标识,那么任何基于该功能的函数都将失效。你仍然可以选择使用类似于xpath的方式搜索元素,就像使用类名一样,但这样做很麻烦、容易出错,并且以后会给你带来麻烦。

1
主要原因是多个具有相同ID的元素会导致Javascript函数(如document.getElementById)出现奇怪和未定义的行为。
这正是问题所在。“未定义的行为”意味着一个用户的浏览器将以一种方式运作(可能只获取第一个元素),另一个用户的浏览器将以另一种方式运作(可能只获取最后一个元素),而另一个用户的浏览器将以另一种方式运作(可能获取所有元素的数组)。编程的整个思想就是向计算机(也就是用户的浏览器)提供关于你想让它做什么的精确指令。当你使用模糊不清的指令,例如非唯一的ID属性时,你会得到不可预测的结果,这不是程序员想要的。
“我为什么要关心别人写的文件?” W3C规范不仅仅是“某些文件”,它们是规则,如果你在编码中遵循这些规则,你可以合理地期望任何浏览器都会遵守。当然,W3C标准很少被所有浏览器完全遵循,但它们是现有的最好的普遍接受的基本规则集。

1
我能想到的主要原因是,具有相同id的多个元素可能会导致Javascript函数(例如document.getElementById)出现奇怪和未定义的行为。
...以及依赖于ids的XPath表达式、爬虫、抓取器等等。如果他们不相信,那就太糟糕了;无论他们是否知道(当他们的网站访问不良时),它都会在最后咬他们一口。

1
为什么社会安全号码或车牌号码应该是唯一的?与任何其他标识符应该是唯一的原因相同。这样它就可以准确地标识一个事物,如果你有这个标识符,你就可以找到那个事物。

1
简短的回答是,在HTML/JavaScript DOM API中,你有一个名为getElementById的函数,它返回一个元素,而不是一组元素。因此,如果你有多个具有相同id的元素,它将不知道选择哪一个。
但这个问题实际上并不愚蠢,因为有理由希望一个id可以引用HTML中的多个元素。例如,用户可能会选择文本并希望加注释。你想用一个标记来显示这个选择。
<span class="Annotation" id="A01">Bla bla bla</span>

如果用户选择的文本跨越了多个段落,则需要将

标签分成多个片段,但该选择的所有片段都应该使用同一个“id”进行标识。

请注意,在过去,您可以将

<a name="..."/> 

在HTML中,您可以使用getElementsByName查找元素。这与此类似。但不幸的是,HTML规范已经开始弃用它,这是一个坏主意,因为它留下了一个重要的用例没有简单的解决方案。

当然,使用XPath,您可以使用任何属性甚至文本节点作为ID来执行任何操作。显然,XPointer规范允许您通过任何XPath表达式引用元素,并将其用作URL片段引用,如

http://my.host.com/document.html#xpointer(id('A01')) 

或其简短版本
http://my.host.com/document.html#A01

或者,其他等效的XPath表达式:
http://my.host.com/document.html#xpointer(/*/descendant-or-self::*[@id = 'A01'])

因此,可以参考名称属性。
http://my.host.com/document.html#xpointer(/*/descendant-or-self::*[@name = 'A01'])

或者你给属性命名为任何你想要的名称。
http://my.host.com/document.html#xpointer(/*/descendant-or-self::*[@annotation-id = 'A01'])

希望这有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接