不同的HTML元素能否使用相同的ID?如果它们是不同类型的元素,这种情况是否有效?例如:
div#foo
span#foo
a#foo
不同的HTML元素能否使用相同的ID?如果它们是不同类型的元素,这种情况是否有效?例如:
div#foo
span#foo
a#foo
不可以。
元素ID应在整个文档中是唯一的。
多个元素可以有相同的ID吗?
可以 - 无论它们是否是相同的标记,浏览器都会呈现页面,即使多个元素具有相同的ID。
这是有效的HTML吗?
不是。这在2023年5月更新的HTML活动标准中仍然是真实的。但是,getElementById
的规范(截至2023年)也说明了它必须返回给定ID的第一个元素,使得在无效文档的情况下行为得到定义。
这种无效的HTML有什么后果?
大多数浏览器不会显示任何指示,而且大多数用户不会在意你的HTML以这种方式“无效”。当调用getElementById
时,大多数(如果不是全部)浏览器会选择具有给定ID的第一个元素。一些查找元素的库继承了这种行为,而其他库(正如gman在他的答案中指出的那样)将使用更明确的querySelector
和querySelectorAll
方法,分别明确地选择匹配的第一个或所有元素。大多数(如果不是全部)浏览器还会将由id选择器(例如#myid
)分配的样式应用于所有具有指定ID的元素。如果这是您期望并打算的,那么就没有意外后果。如果您期望/打算其他事情(例如通过getElementById
返回具有该ID的所有元素,或者使样式仅适用于一个元素),则您的期望将无法实现,并且依赖于这些期望的任何功能都将失败。
一些 JavaScript 库 确实 期望元素的 ID 不重复(参见 wootscootinboogie 的评论 关于 d3.js)
结论
最好遵循标准,但如果您知道您的代码在当前环境中按预期工作,并且这些 ID 以可预测/可维护的方式使用,则我只能想到两个实际的原因不这样做:
力量掌握在你手中!
id
标识符。如果这是为了通过从class
中减少3个字符来节省带宽,那么这与其他一英里长的自定义标签完全相悖,所以我怀疑这不是他们的理由。我无法猜测他们为什么这样做,但他们确实这样做了。 - Exit我认为,某些内容“应该独一无二”和“必须独一无二”是有区别的(即由Web浏览器强制执行)。
ID是否应该是唯一的? 是的。
ID是否必须是唯一的? 不需要,至少IE和FireFox允许多个元素具有相同的ID。
getElementById
,在这种情况下的结果为undefined
,意味着无法确定浏览器如何处理它。 - leogetElementById
的规范实际上确实定义了必须返回具有给定ID的第一个元素(这也是所有浏览器目前处理此情况的方式)-有关更多信息,请参见我下面的答案。 - mltsy即使这些元素类型不同,也可能会给你带来严重的问题...
假设您有3个具有相同ID的按钮:
<button id="myid" data-mydata="this is button 1">button 1</button>
<button id="myid" data-mydata="this is button 2">button 2</button>
<button id="myid" data-mydata="this is button 3">button 3</button>
现在您可以设置一些jQuery
代码,以便在单击 myid
按钮时执行某些操作:
$(document).ready(function ()
{
$("#myid").click(function ()
{
var buttonData = $(this).data("mydata");
// Call interesting function...
interestingFunction();
$('form').trigger('submit');
});
});
<button id="button1" class="mybtn" data-mydata="this is button 1">button 1</button>
<button id="button2" class="mybtn" data-mydata="this is button 2">button 2</button>
<button id="button3" class="mybtn" data-mydata="this is button 3">button 3</button>
$(document).ready(function ()
{
$(".mybtn").click(function ()
{
var buttonData = $(this).data("mydata");
// Call interesting function...
interestingFunction();
$('form').trigger('submit');
});
});
不可以有两个具有相同id的元素。id是唯一的,如果您希望做这样的事情,请使用class。不要忘记使用空格作为分隔符,元素可以具有多个类:
<div class="myclass sexy"></div>
希望能给您提供实用的答案。
我们去Youtube运行以下代码:
Object.fromEntries(Object.entries([...document.querySelectorAll('[id]')].reduce((s, e) => { s[e.id] = (s[e.id] || 0) + 1; return s; }, {})).filter(([k,v]) => v > 1))
并查看所有重复的id。
将上述代码更改为显示重复超过10次的id,以下是它生成的列表
additional-metadata-line: 43
avatar: 46
avatar-link: 43
button: 120
buttons: 45
byline-container: 45
channel-name: 44
container: 51
content: 49
details: 43
dismissable: 46
dismissed: 46
dismissed-content: 43
hover-overlays: 45
img: 90
menu: 50
meta: 44
metadata: 44
metadata-line: 43
mouseover-overlay: 45
overlays: 45
repeat: 36
separator: 43
text: 49
text-container: 44
thumbnail: 46
tooltip: 80
top-level-buttons: 45
video-title: 43
video-title-link: 43
其他使用相同id的网站包括Amazon.com、ebay.com、expedia.com和cnn.com。
显然,ids只是元素上的另一个元数据。
getElementById
已经过时了。您可以使用querySelectorAll
选择所有元素或querySelector
选择第一个元素,而不管选择器如何。因此,如果您想要具有id foo
的所有元素,则可以这样做:
document.querySelectorAll('#foo') // returns all elements with id="foo"
如果您只想要第一个元素,请使用querySelector
document.querySelector('#foo') // returns the first element with id="foo"
document.querySelector('.foo') // returns the first element with class "foo"
document.querySelector('foo') // returns the first <foo> element
document.querySelector('foo .foo #foo') // returns the first element with
// id="foo" that has an ancestor
// with class "foo" who has an
// ancestor <foo> element.
我们可以使用选择器来查找具有相同id的不同元素。
function addClick(selector, add) {
document.querySelector(selector).addEventListener('click', function() {
const e = this.parentElement.querySelector('#value');
e.textContent = parseInt(e.textContent) + add;
});
}
addClick('.e #foo', 1);
addClick('.f #foo', 10);
body { font-size: x-large; font-weight: bold; }
.a #foo { color: red; }
.b #foo { color: green; }
div:nth-child(3) #foo { color: blue; }
#foo { color: purple }
<div class="a"><span id="foo">a</span></div>
<div class="b"><span id="foo">b</span></div>
<div><span id="foo">c</span></div>
<span id="foo">d</span>
<div class="e"><button type="button" id="foo">+1</button>: <span id="value">0</span></div>
<div class="f"><button type="button" id="foo">+10</button>: <span id="value">0</span></div>
<a>
标签可以引用id,例如<a href="#foo">
。点击它将跳转到文档中第一个具有id="foo"
的元素。同样,URL中的哈希标记也具有相同的功能。
<label>
标签具有一个for
属性,指定它们通过id标识的元素。点击标签将点击/激活/聚焦于相应的元素。标签只会影响第一个具有匹配id的元素
label { user-select: none; }
<p>nested for checking</p>
<form>
<div><input type="checkbox" id="foo"><label for="foo">foo</label></div>
</form>
<form>
<div><input type="checkbox" id="foo"><label for="foo">foo (clicking here will check first checkbox)</label></div>
</form>
id
只是你工具箱中的另一种工具。这个:
<div id="unique">One</div>
<div id="unique">Two</div>
在所有浏览器中都可以正常渲染。然而,document.getElementById只返回一个对象,而不是一个数组;你只能通过id标签选择第一个div。如果你使用JavaScript更改了第一个div的id,则第二个ID将可用于document.getElementById(在Chrome、FireFox和IE11上测试通过)。你仍然可以使用其他选择方法选择该div,并且其id属性将被正确返回。
请注意,上述问题为呈现SVG图像的网站打开了潜在的安全漏洞,因为SVG允许包含DOM元素以及它们的id标签(允许通过上传的图像进行脚本DOM重定向)。只要SVG在要替换的元素之前在DOM中定位,图像将接收所有JavaScript事件。
据我所知,目前没有人关注这个问题,但它是真实存在的。
这个:
<div id="unique" id="unique-also">One</div>
在所有浏览器中都能正确渲染。但是,只有以这种方式定义的第一个id才会被使用。例如,在上面的示例中尝试document.getElementById('unique-also');,你将得到null(在Chrome、FireFox和IE11上测试过)。
这样:
<div id="unique unique-two">Two</div>
在所有浏览器中都能正常渲染,但与可以用空格分隔的类标签不同,id标签允许有空格,因此上述元素的id实际上是"unique unique-two",如果在DOM中单独查找"unique"或"unique-two",除非在DOM的其他位置已定义,否则返回null(在Chrome、FireFox和IE11上测试过)。
值得一提的是,在Chrome 26.0.1410.65、Firefox 19.0.2和Safari 6.0.3等浏览器中,如果您有多个具有相同ID的元素,则jquery选择器(至少)将返回具有该ID的第一个元素。
例如:
<div id="one">first text for one</div>
<div id="one">second text for one</div>
并且
alert($('#one').size());
请查看http://jsfiddle.net/RuysX/进行测试。
div#one
。当然,这并不改变它无效的事实。 - Kevin BSLaks的答案是正确的,但需要补充说明的是,x/html规范规定所有id必须在单个html文档中是唯一的。尽管这不完全符合提问者的问题,但有些情况下同一个id可能会附加到多个页面上的不同实体。
例如:
(针对现代浏览器) article#main-content {以一种方式设置样式}
(针对旧版) div#main-content {以另一种方式设置样式}
虽然这可能是一个反模式,但我将其放在这里作为一个争议点。
好的,使用 w3.org 的 HTML 验证器(专门针对 HTML5),ID 必须是唯一的
请考虑以下内容...
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MyTitle</title>
</head>
<body>
<div id="x">Barry</div>
<div id="x">was</div>
<div id="x">here</div>
</body>
</html>
Line 9, Column 14: Duplicate ID x. <div id="x">was</div>
Warning Line 8, Column 14: The first occurrence of ID x was here. <div id="x">Barry</div>
Error Line 10, Column 14: Duplicate ID x. <div id="x">here</div>
Warning Line 8, Column 14: The first occurrence of ID x was here. <div id="x">Barry</div>
...但是原帖明确提到了不同的元素类型,所以考虑以下HTML...
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MyTitle</title>
</head>
<body>
<div id="x">barry
<span id="x">was here</span>
</div>
</body>
</html>
......验证器返回的结果是......
Line 9, Column 16: Duplicate ID x. <span id="x">was here</span>
Warning Line 8, Column 14: The first occurrence of ID x was here. <div id="x">barry
无论是相同的元素类型还是不同的元素类型,如果id被使用了多次,则不符合HTML5的规范。