SLa*_*aks 171

没有.

元素ID在整个文档中应该是唯一的.

  • 不这样做有什么后果? (74认同)
  • 这是不正确的.完全可能有多个具有相同ID的元素.**这通常不是最好的做法**,但它确实偶尔使用.每个人似乎都会引用选择器如何工作,如果你知道你的ID会有冲突,你可以使用父母的选择器,父母下面的ID是唯一的.例如`$('div#car span#size)`和`$('div#truck span#size')`. (66认同)
  • 为什么在为此目的上课时甚至会使用多个相似的id? (17认同)
  • @corsiKa结果是未定义的行为,例如,当有多个#foos时,document.getElementById("#foo")或$("#foo")会返回什么?您将遇到能够使用JS中的这些元素,将它们作为选择器传递给库/ API/Flash等的问题. (15认同)
  • 是的,实际上,可以使用类替换多个ID.但是,类用于应用样式,而不是标识元素,使名称范围更宽,因此可能重叠.特别是如果使用第三方库.作为"标识符"的ID不打算成倍增加,因此显然需要介于两者之间.实际使用是将页面/ dom的各部分组件化为单独的逻辑单元.因此需要使用(至少)2层识别. (6认同)
  • 不.问题的答案"这是否有效?" 不一定要匹配问题的答案"我需要这个吗?","我希望这是有效的吗?" 甚至"这个肮脏的黑客在规范的当前实现中是否有效?" (3认同)
  • 最近有一个d3.js的错误和点击事件处理与多个相同的ID.我观察到的是ID收到动作的第一个实例,即使它是由第二个ID调用的.例如,单击id1的第二个实例,id1的第一个实例将接收操作(更改颜色,文本等). (2认同)
  • 虽然验证器可能认为这是不好的做法,甚至是无效的 HTML 5,但在同一个 HTML 文档中肯定可能有多个 ID。因此,这个答案不是正确的。 (2认同)

Jin*_*Kim 79

我认为某些东西应该是唯一的还是必须是唯一的(即由网络浏览器强制执行)之间存在差异.

ID应该是唯一的吗?是.

ID必须唯一吗?不,至少IE和FireFox允许多个元素具有相同的ID.

  • 根据[spec](http://www.w3.org/TR/html401/struct/global.html#h-7.5.2),这是必须的,而不应该是应该的.(它在大多数浏览器中是否仍然有效?是的.是否有效的HTML?否.对于`getElementById`,这种情况下的结果是[`undefined`](http://www.w3.org/TR/DOM -Level-3-Core/core.html#ID-getElBId),这意味着没有办法告诉浏览器如何选择处理它.) (26认同)
  • Chrome也是如此(此评论撰写时的第22版).:d (6认同)
  • 在 HTML5 中,`getElementById` 的规范实际上确实定义了必须返回具有给定 ID 的 *first* 元素(无论如何,这是所有浏览器目前处理这种情况的方式)- 有关更多信息,请参阅下面的答案。 (5认同)
  • @leo然而,这是浏览器不完全符合标准的现实世界.在这种情况下,它可能是一件好事,因为没有理由强制执行唯一ID. (2认同)

mlt*_*tsy 52

多个元素可以具有相同的ID吗?

是 - 无论它们是否是相同的标签,即使多个元素具有相同的ID,浏览器也会呈现页面.

它是否有效HTML?

不.从HTML 5.1规范开始,这仍然是正确的.但是,规范还说getElementById 必须返回具有给定ID 的第一个元素,这使得在无效文档的情况下行为不是未定义的.

这种无效HTML有什么后果?

大部分(如果不是全部)的浏览器都有,仍然选择与给定的ID,打电话时的第一要素getElementById.大多数通过ID查找元素的库都会继承此行为.大多数(如果不是全部)浏览器还将id-selectors(例如#myid)分配的样式应用于具有指定ID的所有元素.如果这是您期望和打算的,那么就不会产生意想不到的后果.如果您期望/打算其他东西(例如,对于具有该ID的所有元素都要返回,或者样式仅适用于一个元素)那么您的期望将无法满足,任何依赖于这些期望的功能都将失败.

当多个元素具有相同的ID时,一些javascript库确实存在未满足的期望(请参阅wootscootinboogie关于d3.js 的评论)

结论

如果您的代码在当前环境中按预期工作,并且这些ID以可预测/可维护的方式使用,那么考虑不执行此操作只有两个实际原因:

  1. 为了避免您出错的可能性,当您使用的某个库实际上在多个元素具有相同ID时会出现故障.
  2. 为了保持您的网站/应用程序与多个元素具有相同ID时出现故障的库或服务(或开发人员!)的向前兼容性,您将来可能会遇到这种情况.

权力是你的!


Len*_*rri 23

即使元素属于不同类型,它也会给你带来一些严重的问题......

假设您有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>
Run Code Online (Sandbox Code Playgroud)

现在,您可以设置一些jQuery代码,以便myid在单击按钮时执行某些操作:

$(document).ready(function ()
{
    $("#myid").click(function ()
    {
        var buttonData = $(this).data("mydata");

        // Call interesting function...
        interestingFunction();

        $('form').trigger('submit');
    });
});
Run Code Online (Sandbox Code Playgroud)

你会期待什么?单击每个按钮将使用jQuery执行单击事件处理程序设置.不幸的是,它不会发生.只有第一个按钮调用点击处理程序.点击时其他2个什么都不做.就好像它们根本不是按钮!

所以总是分配不同IDsHTML元素.这将让你对抗奇怪的事情.:)

<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>
Run Code Online (Sandbox Code Playgroud)

现在,如果您希望单击任何按钮时单击事件处理程序运行,如果您更改jQuery代码中的选择器以使用CSS应用于它们的类,则它将完美地工作:

$(document).ready(function ()
{
    $(".mybtn").click(function ()
    {
        var buttonData = $(this).data("mydata");

        // Call interesting function...
        interstingFunction();

        $('form').trigger('submit');
    });
});
Run Code Online (Sandbox Code Playgroud)


Gaz*_*ler 22

具有相同id的第二个元素无效.ID是唯一的,如果您希望执行类似的操作,请使用类.不要忘记,通过使用空格作为分隔符,元素可以有多个类:

<div class="myclass sexy"></div>
Run Code Online (Sandbox Code Playgroud)


Nic*_*ele 12

HTML的官方规范声明id标签必须是唯一的,官方规范还指出,如果渲染可以完成,它必须(即HTML中没有"错误",只有"无效"HTML). 因此,以下是id标签在实践中的实际工作方式.它们都是无效的,但仍然有效:

这个:

<div id="unique">One</div>
<div id="unique">Two</div>
Run Code Online (Sandbox Code Playgroud)

在所有浏览器中渲染都很好.但是,document.getElementById只返回一个对象,而不是一个数组; 你只能通过id标签选择第一个div.如果您要使用JavaScript更改第一个div的ID,则可以使用document.getElementById(在Chrome,FireFox和IE11上测试)访问第二个ID.您仍然可以使用其他选择方法选择div,并且将正确返回它的id属性.

请注意,上述问题在呈现SVG图像的站点中打开了潜在的安全漏洞,因为允许SVG包含DOM元素,并且还允许其上包含id标记(允许脚本DOM通过上载的图像重定向).只要SVG在它替换的元素之前位于DOM中,图像就会接收所有针对其他元素的JavaScript事件.

据我所知,目前这个问题并没有被任何人所关注,但它确实存在.

这个:

<div id="unique" id="unique-also">One</div>
Run Code Online (Sandbox Code Playgroud)

也适用于所有浏览器.但是,如果你尝试了document.getElementById('unique-also'),那么只使用你用这种方式定义的第一个 id; 在上面的示例中,您将返回null(在Chrome,FireFox和IE11上测试).

这个:

<div id="unique unique-two">Two</div>
Run Code Online (Sandbox Code Playgroud)

然而,在所有浏览器中渲染都很好,不像可以用空格分隔的类标签,id标签允许空格,所以上面元素的id实际上是"唯一的唯一 - 两个",并且要求dom为"unique"或者"unique-two"在隔离中返回null,除非在DOM的其他地方另有定义(在Chrome,FireFox和IE11上测试).


den*_*kin 6

无论如何,至少在 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>
Run Code Online (Sandbox Code Playgroud)

alert($('#one').size());
Run Code Online (Sandbox Code Playgroud)

请参阅http://jsfiddle.net/RuysX/进行测试。


gma*_*man 6

务实的回答怎么样。

让我们去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))
Run Code Online (Sandbox Code Playgroud)

并查看所有重复的 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
Run Code Online (Sandbox Code Playgroud)

其他多次使用相同 ID 的网站包括 Amazon.com、ebay.com、expedia.com、cnn.com

显然 id 只是元素上的另一块元数据。

getElementById已经过时了。无论选择器如何,您都可以querySelectorAll用于所有元素或querySelector第一个元素,因此如果您想要所有带有 id 的元素,foo那么

document.querySelectorAll('#foo')  // returns all elements with id="foo"
Run Code Online (Sandbox Code Playgroud)

好像你只想要第一个元素使用 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.
Run Code Online (Sandbox Code Playgroud)

我们可以看到使用选择器我们可以找到具有相同 id 的不同元素。

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))
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
document.querySelectorAll('#foo')  // returns all elements with id="foo"
Run Code Online (Sandbox Code Playgroud)

id 唯一重要的地方

  • <a>标签可以像<a href="#foo">. 单击它会将文档跳转到带有 的第一个元素id="foo"。类似地,URL 中的哈希标签实际上是相同的功能。

  • <label>标签有一个for属性,用于指定它们通过 id 标记的元素。单击标签单击/激活/将焦点赋予相应的元素。标签只会影响具有匹配 id 的第一个元素

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.
Run Code Online (Sandbox Code Playgroud)
function addClick(selector, add) {
  document.querySelector(selector).addEventListener('click', function() {
    const e = this.parentElement.querySelector('span');
    e.textContent = parseInt(e.textContent) + add;
  });
}
addClick('.e #foo', 1);
addClick('.f #foo', 10);
Run Code Online (Sandbox Code Playgroud)

否则,id它只是工具箱中的另一个工具。


Rob*_*obW 5

SLaks的答案是正确的,但作为补充说明,x / html规范指定在一个(单个)html文档中所有id必须唯一。尽管这并不是操作人员要求的,但可能存在有效的实例,其中相同的ID跨多个页面附加到不同的实体。

例:

(适用于现代浏览器)article#main-content { 样式化 }
(适用于旧版)div#main-content { 样式化另一种 }

不过可能是反模式。只是作为恶魔的拥护者离开这里。


bar*_*ker 5

嗯,使用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>
Run Code Online (Sandbox Code Playgroud)

验证器响应...

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>
Run Code Online (Sandbox Code Playgroud)

...但是OP特别指出 - 不同的元素类型怎么样。因此,请考虑以下 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>
Run Code Online (Sandbox Code Playgroud)

...验证器的结果是...

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
Run Code Online (Sandbox Code Playgroud)

结论:

无论哪种情况(相同元素类型或不同元素类型),如果多次使用 id,则不会被视为有效的 HTML5。