【发布时间】:2014-10-13 13:44:42
【问题描述】:
我正在考虑编写代码来生成可能具有重复属性的 HTML 标记,如下所示:
<div data-foo="bar" class="some-class" data-foo="baz">
这是合法的 HTML 吗? data-foo-values 之一是否优先于另一个?我可以指望半现代浏览器(IE >= 9)来解析它而不会窒息吗?
或者我要在这里做一些非常愚蠢的事情?
【问题讨论】:
标签: html
我正在考虑编写代码来生成可能具有重复属性的 HTML 标记,如下所示:
<div data-foo="bar" class="some-class" data-foo="baz">
这是合法的 HTML 吗? data-foo-values 之一是否优先于另一个?我可以指望半现代浏览器(IE >= 9)来解析它而不会窒息吗?
或者我要在这里做一些非常愚蠢的事情?
【问题讨论】:
标签: html
在一个元素中使用相同的属性名称两次是无效的。对此的权威参考有些复杂,因为旧的 HTML 版本名义上是基于 SGML 的,并且对 SGML 标准的规范性参考暗示了限制。在 HTML5 PR 中,第 8.1.2.3 节 Attributes 明确指出:“同一个起始标记上不得有两个或多个属性,它们的名称是不区分大小写的 ASCII 匹配。”
实际发生的情况是后一个属性被忽略。好吧,未来的浏览器可能会这样做。在 DOM 中,属性作为元素节点以及 attributes 对象的属性出现,因此没有自然的方式来存储两个值。
【讨论】:
这在技术上无效,但每个浏览器都会忽略 HTML 文档中的重复属性并使用第一个值(在您的情况下为 data-foo="bar")。
在标签中使用相同的属性名称两次是被认为是内部解析错误。如果您担心的话,它会导致您的文档无法通过验证。但是,重要的是要了解 HTML 5 定义了预期结果,即使在您遇到“解析错误”的情况下也是如此。 允许解析器在遇到错误时停止,但如果它选择不停止它必须产生规范中描述的特定结果。实际上,当遇到 HTML 文档中的错误时,没有浏览器会选择停止(XML/XHTML 是另一回事),因此所有现代浏览器都会成功且一致地处理这种情况。
WHATWG HTML 规范在section 12.2.4.33 "Attribute name state" 中描述了这种情况:
当用户代理离开属性名称状态时(如果合适,在发出标记令牌之前),必须将完整的属性名称与同一令牌上的其他属性进行比较; 如果令牌上已经有一个同名的属性,那么这是一个解析错误,必须删除新属性,以及与之关联的值(如果有的话)。
另见its description of "parse error" from the opening of section 12.2 "Parsing HTML documents":
解析算法中的某些点被称为解析错误。解析错误的错误处理是明确定义的(这是整个规范中描述的处理规则),但是用户代理在解析 HTML 文档时,可能会在他们遇到的第一个解析错误时中止解析器不希望应用本规范中描述的规则。
【讨论】:
我想为接受的优秀答案添加评论,但我的声誉不够高。
我想补充一点,重要的是要考虑如何编译您的代码。
例如,Angular 会删除先前的重复(非 Angular)class 属性,并且只保留最后一个。
注意:Angular 还使用ngClass 和任何[class.class-name] 属性修改类属性的值。
这也是你可以使用 linter 的东西。
请参阅 htmlhint (attr-no-duplication) 或 htmllint (attr-no-dup)。
【讨论】: