只需浏览google maps源代码。在标题中,他们有2个div,其中id =“ search”一个包含另一个,并且还具有jstrack =“ 1”属性。有一种形式将它们分开,如下所示:

<div id="search" jstrack="1">
    <form action="/maps" id="...rest isn't important">
        ...
        <div id="search">...


由于这是google,我认为这不是一个错误。

那么违反此规则真的有多严重?只要谨慎选择CSS和dom,为什么不重用id一样的类?是否有人故意这样做?如果是,为什么?

评论

“由于这是谷歌,所以我认为这不是一个错误。” -> Google并非万无一失。他们像我们其他人一样犯错误。

实际上,谷歌的家伙脑子里塞满了SEARCH,因此他们无法想到其他任何ID:P

我觉得该页面是由不同的html片段呈现的,因此一个片段中的一个开发人员使用了该id,而另一个片段中的其他开发人员也发生了同样的情况。

整个问题“真的有多严重”让我想起了这个问题:xkcd.com/292

@DanielRoseman xkcd也可以做到这一点:what-if.xkcd.com/23/#question

#1 楼

规范说UNIQUE

HTML 4.01规范说ID在文档范围内必须是唯一的。

HTML 5规范说了同样的话,但是换句话说。它说ID在它的home子树中必须是唯一的,如果我们阅读ID的定义,它基本上就是文档。

避免重复

但是,由于HTML渲染器在处理HTML渲染时非常宽容,因此允许重复的ID。应尽可能避免这种情况,并在以JavaScript的ID编程访问元素时严格避免。我不确定找到多个匹配元素时应返回哪个getElementById函数?是否应该:


返回错误?
返回第一个匹配的元素?
返回最后一个匹配的元素?
返回一组匹配的元素?
什么都不返回?

但是,即使这些天浏览器能够可靠地运行,但由于违反规范,因此没有人能保证这种行为。因此,我建议您不要在同一文档中重复ID。

评论


@missingno:我添加了指向HTML 5规范的链接,该链接讨论的是同一件事,但措辞不同。

– Robert Koritnik
2011-12-27 20:26

根据DOM规范,“如果多个元素具有具有该值的ID属性,则返回的内容是不确定的”(这意味着没有定义的“正确”结果,而不是未定义的实际值)。依靠不确定的行为很少是一个好主意。

–lonesomeday
2011-12-28 at 0:22

值得一提的是HTML5,当可能会尝试为多个事物分配相同的ID时,data-属性会派上用场。这使您可以拥有许多具有相同的通用数据属性的不同ID。尽管如此,我所知道的所有浏览器都会忽略未知属性,因此对于几乎所有缺乏完整HTML支持的现代浏览器来说,它们可能都是安全的。

– Tim Post
2012年3月3日15:53

@JoachimSauer:使用数据属性时,可以具有键-值对,而使用CSS类时,键-值对不正确。在那种情况下,它们都像布尔属性。元素是否具有CSS类。如果您想要CSS类的值,则必须以某种方式将它们组合为CSS类名,然后进行解析。我希望您现在可以看到使用数据属性的好处。当您仅通过$(elem).data(“ something”)引用data-something =“ 123”属性时,jQuery也直接支持它们。

– Robert Koritnik
2012年9月4日上午10:39

@RobertKoritnik:当然可以!我没想到那个用例。我只想到了id =“ search”的情况。

– Joachim Sauer
2012年9月4日上午10:46

#2 楼

您问“有多糟”。因此,充实@RobertKoritnik的(完全正确)的答案有点...

该代码不正确。错误不会以灰色阴影出现。该代码违反标准,因此不正确。它将无法通过验证检查,它应该。

那就是说,目前市场上没有浏览器会抱怨它,或者根本没有问题。浏览器有权投诉该浏览器,但是任何浏览器的当前版本都没有。这并不意味着将来的版本可能不会对此代码造成严重影响。

您尝试使用该ID作为选择器的行为(在CSS或javascript中)是无法猜测的,并且可能因浏览器而异。我想可以做一个研究,看看每个浏览器对此有何反应。我认为在最好的情况下,它将像“ class =”一样对待它,并选择它们的列表。 (不过,这可能会使JavaScript库感到困惑-如果我是jQuery的作者,我可能已经优化了选择器代码,因此如果您使用以“#”开头的选择器来找我,那么我希望得到一个对象,并得到一个列表可能会让我完全困惑。)

它也可能选择第一个,或者可能选择最后一个,或者不选择其中任何一个,或者使浏览器完全崩溃。

“有多糟”然后完全取决于特定浏览器实施HTML规范的严格程度以及在遇到违反该规范时的行为。

编辑:我只是碰巧今天遇到了这个。我正在从各种类型的实体上的搜索表单中提取各种组件,以生成用于此站点的大型综合报告实用程序,我将远程页面的搜索表单加载到隐藏的div中并将其放入我的选择适当的实体类型作为报告源时的报告生成器。因此,存在表单的隐藏版本,并且报表生成器中显示了一个版本。在所有情况下,随附的JavaScript均按ID指代元素,页面上现在有两个元素-隐藏的元素和显示的元素。

jQuery似乎在做什么正在选择我的第一个,在所有情况下都是我不想要的。

我正在通过编写选择器来指定要获取的页面区域来解决此问题字段(例如:$('#containerDiv #specificElement'))。但是您的问题有一个答案-Chrome上的jQuery在遇到这种规范违规时肯定会表现出特定的方式。

评论


...一个相关的问题:关于CSS快速配置文件中ID义务的stackoverflow.com/q/29295824/287948。

– Peter Krauss
2015年3月27日14:22

“不正确的不是灰色阴影。”我经常看到这一点,这是技术上正确的事情之一,但在生活或编程中不是“正确的”事情。您可以在回答中完全间接地涵盖这一点,我可以阐述一下,但是《大爆炸理论》中的这一幕做得很好,我会让它为我说话,并希望使某人发笑... Stuart vs Sheldon youtube.com/看吗?v = F_1zoX5Ax9U

–夜猫子
16年1月1日在21:42

这是一个有8年历史的答案,但我认为您在OP问题上夸张的方式非常不均衡,但又不用抱怨浏览器对重复ID的宽容和危险行为,这比OP试图做的要糟糕得多。

–erandros
19-10-8在15:41



#3 楼

到底有多糟?


让我哭泣
这是无效的
许多javascript库无法按预期运行
这会使您的代码令人困惑

经验表明,主流浏览器中的getElementById将返回文档中的第一个匹配元素。但是将来可能并非总是如此。

当给jQuery一个ID如#foo时,它使用getElementById并模仿行为。如果您必须解决此问题(这很可悲),则可以使用$(“ *#foo”),这将说服jQuery使用getElementsByTagName并返回所有匹配元素的列表。

我经常为其他站点编写代码,我必须解决此问题。在一个公正的世界中,我不必通过检查ID是否唯一来重新设计功能。 ID应该始终是唯一的。世界很残酷,这就是我哭泣的原因。

评论


这个回答让我哭了……笑声!

– A1rPun
15年6月30日在10:23

#4 楼

您可以做很多事情-但这并不意味着您应该做。

作为程序员(通常来说),我们的生活是建立在精确和遵循规则的基础上-这是一条规则易于遵循,这是我们所做工作的基础-我们喜欢(取决于)给定范围内的唯一标识符...

打破规则是我们可以做的,因为浏览器是太宽容了-但是,如果浏览器严格要求格式正确和有效的HTML,那么我们所有人都会过得更好,因为它带来的少量痛苦早已得到回报!

因此,真的那么糟糕吗?作为程序员,您怎么能问?这是危害文明的罪行(-:


附录:


你写的是浏览器太包容了,就像不好的事情


我愿意,因为它是-我们不是在谈论复杂的规则,而是在谈论使事物结构良好,并应用可以机械测试的规则,从而使之更容易如果浏览器很严格,那么这些工具将很快适应这种情况-并非如此,他们没有这样做,某种程度上是他们利用了失败的结果。如果MS和Netscape没有通过允许不受限制的HTML来搞砸它,那么电子邮件本来是一种更好的媒介,而当一种复杂得多的“电子邮件标记语言”具有对引用文本的显式支持时,电子邮件将为我们提供更好的工具...但是航行,类似地,我们无法关闭浏览器允许的稳定门(应该,HTML5应该具有),但是我们可以t

评论


您写的是,浏览器适应性很强,这是一件坏事,但是您肯定不相信吗?

– KaptajnKold
2011-12-27 22:42

我不能代表墨菲(Murph)发言,但是我可以肯定这是一件很糟糕的事情。再有,如果没有这种宽恕,网络可能不会像我们所知道的那样具有增长的冲动。

– Andrea
2011-12-27 23:37

@Andrea:互联网不会像我们所知道的那样增长。它的增长速度会更慢。但这也将为正确的代码和错误的代码提供更坚实的基础。快速但草率的工作可能会起作用,但我更喜欢速度较慢但正确的方法。特别是因为这并不是说我们只谈论几年的增长。

–尼科尔·波拉斯(Nicol Bolas)
2011-12-28 5:40

@Andrea我敢打赌它会以几乎一样快的速度增长-这些工具将可以解决问题。在许多情况下,工具是不良标记的根本原因。事实是,人们倾向于做最少的事情-“结构良好”的步骤相对较小,足够容易测试和执行,而人们本来可以在没有很大压力的情况下适应的

–墨菲
2011-12-28 11:36



浏览器可以容纳并不可怕。他们都以不同的方式包容真是太可怕了。

–丹·雷(Dan Ray)
2011-12-29 18:45

#5 楼

在脚本中:getElementByID将仅返回第一个匹配项。
在CSS中:#id将影响具有该ID的所有元素。
在Browser Render中将无效。

这是w3c标准的行为。

https://dom.spec.whatwg.org/#interface-nonelementparentnode

评论


这是一种可能的行为。 getElementById可以完美地返回任何元素,甚至可以返回null对象。 CSS效果可以作用于任何元素,或者不作用于所有元素。否则浏览器可能崩溃。超出标准,行为未定义

–rds
2011-12-27 22:35

这不是超出标准的范围,因为标准指定了在这些情况下的操作。所以不,getElementById无法返回任何元素,标准明确要求我将返回第一个匹配项。我同意未定义标准的行为,您不了解的是所有这些情况都是该标准的一部分。

–巴特杯
2014年4月3日在21:27

如果该答案实际上包括标准的相关部分(或至少是部分编号)的引用作为参考,则可能会更好。

– yoniLavi
15年10月28日在20:30

@yoniLavi更新。

–巴特杯
15-10-28在20:35

谢谢@Bart。您说得很对:)标准中说:“返回ID为elementId的节点后代中的第一个元素。”

– yoniLavi
15-10-28在23:32