Nhiều phần tử HTML khác nhau có thể có cùng một ID nếu chúng là các phần tử khác nhau không?


139

Một kịch bản như thế này có hợp lệ không?:

div#foo
span#foo
a#foo

23
Mặc dù đôi khi có thể, nó không bao giờ hợp lệ.
Paul Creasey

2
Với tất cả những gì đã nói ở trên, đáng lưu ý rằng có khả năng bắt gặp nhiều ID giống nhau trong một tài liệu có nội dung do tác nhân tạo ra (nghĩ khung, mv *, phản ứng, polymer ...). Đó là nếu bất cứ ai thắc mắc tại sao một trang web XYZ trông rất chuyên nghiệp lại chứa đầy mã hóa thực hành tồi như vậy .
Lukasz Matysiak

Câu trả lời:


180

Không.

ID phần tử phải là duy nhất trong toàn bộ tài liệu.


85
Hậu quả của việc không làm như vậy là gì?
corsiKa

16
@corsiKa hậu quả là hành vi không xác định, ví dụ: document.getEuityById ("# foo") hoặc $ ("# foo") trở lại khi có nhiều #foos? Bạn sẽ gặp vấn đề khi có thể làm việc với các yếu tố này từ JS, chuyển chúng dưới dạng bộ chọn sang thư viện / API / Flash, v.v.
mrooney

76
Điều này là không đúng. Hoàn toàn có thể có nhiều yếu tố với cùng một ID. Nó thường không phải là thực hành tốt nhất , nhưng nó có những công dụng không thường xuyên của nó. Mọi người dường như đều trích dẫn cách các công cụ chọn hoạt động, nếu bạn biết rằng bạn sẽ có ID xung đột, bạn sử dụng công cụ chọn của mình với cha mẹ, trong đó ID dưới gốc sẽ là duy nhất. ví dụ $('div#car span#size)$('div#truck span#size').
BJury

18
Tại sao thậm chí sử dụng nhiều id tương tự khi bạn có lớp cho mục đích này?
Max Yari

6
Có, trong thực tế, nhiều ID có thể được thay thế bằng cách sử dụng các lớp. Tuy nhiên, các lớp được dự định để áp dụng các kiểu, không xác định các thành phần, làm cho phạm vi của tên rộng hơn nhiều và do đó có khả năng chồng lấp. Đặc biệt nếu sử dụng thư viện của bên thứ 3. Id là 'định danh' không có ý định được nhân lên nên rõ ràng cần có một cái gì đó ở giữa. Việc sử dụng thực tế là thành phần hóa các phần của một trang / dom thành các đơn vị logic riêng biệt. Do đó, sử dụng (ít nhất) nhận dạng 2 lớp là bắt buộc.
Alen Siljak

85

Tôi nghĩ rằng có một sự khác biệt giữa việc một cái gì đó NÊN là duy nhất hay PHẢI là duy nhất (tức là được thực thi bởi các trình duyệt web).

ID có nên là duy nhất? ĐÚNG.

ID phải là duy nhất? KHÔNG, ít nhất IE và FireFox cho phép nhiều yếu tố có cùng ID.


6
Chrome cũng vậy (v22 tại thời điểm bình luận này được viết). : D
omninonsense

27
Theo thông số kỹ thuật , đây là PHẢI chứ không phải NÊN. (Liệu nó vẫn làm việc trong hầu hết các trình duyệt Có Có HTML hợp lệ số Ngoài ra, đối?.? getElementById, Kết quả trong những trường hợp như vậy được undefined, có nghĩa là không có cách để nói như thế nào một trình duyệt có thể chọn để xử lý nó.)
leo

2
@leo tuy nhiên đây là thế giới thực nơi các trình duyệt không tuân thủ đầy đủ các tiêu chuẩn. Trong trường hợp này, đó có thể là một điều tốt, vì không có lý do gì để thực thi ID duy nhất.
BJury

1
Trong HTML5, thông số kỹ thuật getElementByIdthực sự xác định rằng phần tử đầu tiên có ID đã cho phải được trả về (đó là cách tất cả các trình duyệt hiện đang xử lý tình huống này) - xem câu trả lời của tôi dưới đây để biết thêm.
mltsy

1
Đừng khóc, hãy sử dụng jQuery. @leo
Máxima Alekz

67

Nhiều yếu tố có thể có cùng một ID không?

Có - cho dù chúng có cùng một thẻ hay không, các trình duyệt sẽ hiển thị trang ngay cả khi nhiều thành phần có cùng ID.

HTML có hợp lệ không?

Không. Điều này vẫn đúng với thông số HTML 5.1 . Tuy nhiên, thông số kỹ thuật cũng cho biết getElementById phải trả về phần tử đầu tiên với ID đã cho , khiến hành vi không được xác định trong trường hợp tài liệu không hợp lệ.

Hậu quả của loại HTML không hợp lệ này là gì?

Hầu hết (nếu không phải tất cả) các trình duyệt đã được lựa chọn và vẫn làm chọn phần tử đầu tiên với một ID nhất định, khi gọi getElementById. Hầu hết các thư viện tìm các phần tử bằng ID đều kế thừa hành vi này. Hầu hết các trình duyệt (nếu không phải tất cả) cũng áp dụng các kiểu được gán bởi bộ chọn id (ví dụ #myid) cho tất cả các thành phần có ID được chỉ định. Nếu đây là những gì bạn mong đợi và dự định, thì không có hậu quả ngoài ý muốn. Nếu bạn mong đợi / có ý định gì đó (ví dụ: tất cả các yếu tố có ID đó sẽ được trả lại hoặc cho kiểu chỉ áp dụng cho một yếu tố) thì kỳ vọng của bạn sẽ không được đáp ứng và bất kỳ tính năng nào dựa trên những kỳ vọng đó sẽ không thành công.

Một số thư viện javascript làm có những kỳ vọng đó không được đáp ứng khi có nhiều yếu tố có cùng một ID (xem bình luận wootscootinboogie của khoảng d3.js)

Phần kết luận

Tốt nhất là tuân thủ các tiêu chuẩn, nhưng nếu bạn biết mã của mình hoạt động như mong đợi trong môi trường hiện tại của mình và các ID này được sử dụng theo cách có thể dự đoán / duy trì được, thì chỉ có 2 lý do thực tế không làm điều này:

  1. Để tránh những cơ hội mà bạn là sai, và một trong những thư viện bạn sử dụng thực sự không trục trặc khi nhiều yếu tố có cùng một ID.
  2. Để duy trì khả năng tương thích về phía trước của trang web / ứng dụng của bạn với các thư viện hoặc dịch vụ (hoặc nhà phát triển!) Bạn có thể gặp phải trong tương lai, điều đó gây ra sự cố khi nhiều yếu tố có cùng một ID - đó là một khả năng hợp lý vì về mặt kỹ thuật, không hợp lệ HTML.

Sức mạnh là của bạn!


Câu trả lời tuyệt vời. nó luôn luôn là tốt nhất nếu bạn tuân thủ các tiêu chuẩn.
EKanadily

25

Ngay cả khi các yếu tố thuộc các loại khác nhau, nó có thể gây ra cho bạn một số vấn đề nghiêm trọng ...

Giả sử bạn có 3 nút có cùng 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>

Bây giờ bạn thiết lập một số jQuerymã để làm một cái gì đó khi các myidnút được bấm:

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

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

        $('form').trigger('submit');
    });
});

Bạn mong đợi điều gì? Mỗi nút được nhấp sẽ thực hiện thiết lập xử lý sự kiện nhấp bằng jQuery. Thật không may, nó sẽ không xảy ra. CHỈ nút 1 gọi trình xử lý nhấp chuột. 2 cái còn lại khi nhấp vào không làm gì cả. Như thể họ không có nút nào cả!

Vì vậy, luôn luôn chỉ định khác nhau IDscho HTMLcác yếu tố. Điều này sẽ giúp bạn được bảo vệ chống lại những điều kỳ lạ. :)

<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>

Bây giờ nếu bạn muốn trình xử lý sự kiện nhấp chạy khi bất kỳ nút nào được nhấp, nó sẽ hoạt động hoàn hảo nếu bạn thay đổi bộ chọn trong mã jQuery để sử dụng CSSlớp được áp dụng cho chúng như thế này:

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

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

        $('form').trigger('submit');
    });
});

Điều gì xảy ra nếu tôi có một "#content" mà tôi đã tham chiếu trong một biến và # my-div #content mà tôi chỉ có trong một vài phút sau đó tôi loại bỏ nút được tham chiếu và quên biến đó, sau đó # div #content thực hiện myDiv.outerHTML = myDiv.innerHTML để thay thế bản gốc. Điều này giúp tiết kiệm nhu cầu sao chép tất cả các kiểu và nội dung của #content vào #decoy và làm điều tương tự. Điều này có ý nghĩa khi thực hiện chuyển đổi.
Dmitry

Điều này có nghĩa là, ngay cả khi tôi sử dụng 'chắp thêm' để thêm nhiều phần tử của cùng một id, DOM chỉ coi phần tử đầu tiên là có thật, lý tưởng là 1 ID = 1 Phần tử
Karan Kaw

22

Số hai yếu tố có cùng id là không hợp lệ. ID là duy nhất, nếu bạn muốn làm một cái gì đó như thế, hãy sử dụng một lớp. Đừng quên rằng các phần tử có thể có nhiều lớp bằng cách sử dụng khoảng trắng làm dấu phân cách:

<div class="myclass sexy"></div>

12

Thông số chính thức cho HTML nói rằng các thẻ id phải là duy nhất VÀ thông số chính thức cũng nói rằng nếu kết xuất có thể được hoàn thành, thì nó phải (nghĩa là không có lỗi nào như "lỗi" trong HTML, chỉ có HTML "không hợp lệ"). Vì vậy, sau đây là cách thẻ id thực sự hoạt động trong thực tế . Tất cả đều không hợp lệ , nhưng vẫn hoạt động:

Điều này:

<div id="unique">One</div>
<div id="unique">Two</div>

Riders tốt trong tất cả các trình duyệt. Tuy nhiên, document.getEuityById chỉ trả về một đối tượng, không phải là một mảng; bạn sẽ chỉ có thể chọn div đầu tiên thông qua thẻ id. Nếu bạn đã thay đổi id của div đầu tiên bằng JavaScript, thì ID thứ hai sẽ có thể truy cập được bằng document.getEuityById (đã thử nghiệm trên Chrome, FireFox & IE11). Bạn vẫn có thể chọn div bằng các phương thức lựa chọn khác và thuộc tính id của nó sẽ được trả về chính xác.

Xin lưu ý vấn đề trên mở ra một lỗ hổng bảo mật tiềm ẩn trong các trang web hiển thị hình ảnh SVG, vì các SVG được phép chứa các phần tử DOM và cả thẻ id trên chúng (cho phép chuyển hướng DOM qua hình ảnh được tải lên). Miễn là SVG được định vị trong DOM trước phần tử mà nó thay thế, hình ảnh sẽ nhận được tất cả các sự kiện JavaScript dành cho phần tử khác.

Vấn đề này hiện không phải trên radar của bất cứ ai như tôi biết, nhưng nó là sự thật.

Điều này:

<div id="unique" id="unique-also">One</div>

Cũng làm cho tốt trong tất cả các trình duyệt. Tuy nhiên, chỉ id đầu tiên bạn xác định theo cách này được sử dụng, nếu bạn đã thử document.getEuityById ('unique-cũng'); trong ví dụ trên, bạn sẽ được trả về null (được thử nghiệm trên Chrome, FireFox & IE11).

Điều này:

<div id="unique unique-two">Two</div>

Tuy nhiên, cũng hiển thị tốt trong tất cả các trình duyệt, tuy nhiên, không giống như các thẻ lớp có thể được phân tách bằng khoảng trắng, thẻ id cho phép khoảng trắng, vì vậy id của phần tử trên thực sự là "unique unique-Two" và yêu cầu dom cho "unique" hoặc "độc nhất hai" trả về null, trừ khi được định nghĩa ở nơi khác trong DOM (được thử nghiệm trên Chrome, FireFox & IE11).


1
"thẻ id cho phép khoảng trắng" - Mặc dù, theo thông số kỹ thuật , "Giá trị không được chứa bất kỳ ký tự khoảng trắng nào".
MrWhite

Tôi đồng ý. Tuy nhiên, có thông số kỹ thuật và đó là cách các trình duyệt hoạt động. Các trình duyệt trong lịch sử coi thông số kỹ thuật là một mục tiêu, nhưng không nghiêm ngặt đối với nhiều mục. Tôi nghĩ rằng họ làm điều này bởi vì nếu họ gặp thông số kỹ thuật, nó sẽ phá vỡ rất nhiều trang web hiện có hoặc một cái gì đó. Tôi đề cập ở trên rằng mặc dù những thứ này hoạt động, chúng không hợp lệ.
Nick Steele

5

Câu trả lời SLaks là chính xác, nhưng như một ghi chú phụ lục rằng các thông số x / html chỉ định rằng tất cả các id phải là duy nhất trong một tài liệu html (đơn) . Mặc dù đó không chính xác là những gì op yêu cầu, có thể có những trường hợp hợp lệ trong đó cùng một id được gắn vào các thực thể khác nhau trên nhiều trang.

Thí dụ:

(phục vụ cho các trình duyệt hiện đại) bài viết # main-content { theo kiểu một cách }
(được phục vụ theo di sản) div # main-content { theo kiểu khác }

Có lẽ là một antipotype mặc dù. Chỉ cần rời khỏi đây như là một điểm ủng hộ của quỷ.


1
Điểm tốt. Mặc dù nội dung được tạo động được cho là được chèn vào một trang khác nên tránh hoàn toàn id. Id giống như toàn cầu trong các ngôn ngữ lập trình, bạn có thể sử dụng chúng và có những trường hợp hợp lệ trong đó là một bản hack hay giúp đơn giản hóa mọi thứ. Đó là một thực hành tốt để xem xét làm mọi thứ ngay trước khi thực hiện hack.
tâm lý

4

Và với giá trị của nó, trên Chrome 26.0.1410,65, Firefox 19.0.2 và Safari 6.0.3 ít nhất, nếu bạn có nhiều phần tử có cùng ID, các bộ chọn jquery (ít nhất) sẽ trả về phần tử đầu tiên có ID đó.

ví dụ

<div id="one">first text for one</div>
<div id="one">second text for one</div>

alert($('#one').size());

Xem http://jsfiddle.net/RuysX/ để kiểm tra.


Trừ khi bạn sử dụng bộ chọn phức tạp hơn, chẳng hạn như div#oneĐiều đó tất nhiên sẽ không thay đổi thực tế là nó không hợp lệ.
Kevin B

Có thể câu trả lời này là đúng, tôi đang nói điều này từ kinh nghiệm.
Dibyanshu Jaiswal

4

Chà, sử dụng trình xác thực HTML tại w3.org , cụ thể cho HTML5, ID phải là duy nhất

Hãy xem xét những điều sau đây ...

<!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>

trình xác nhận trả lời với ...

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>

... nhưng OP đã nêu cụ thể - những gì về các loại yếu tố khác nhau. Vì vậy, hãy xem xét HTML sau đây ...

<!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>

... kết quả từ trình xác nhận là ...

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

Phần kết luận:

Trong cả hai trường hợp (cùng loại phần tử hoặc loại phần tử khác nhau), nếu id được sử dụng nhiều lần, nó không được coi là HTML5 hợp lệ.


2

Chúng ta có thể sử dụng tên lớp thay vì sử dụng id. id html nên là duy nhất nhưng các lớp thì không. khi lấy dữ liệu bằng tên lớp có thể giảm số dòng mã trong tệp js của bạn.

$(document).ready(function ()
{
    $(".class_name").click(function ()
    {
        //code
    });
});


1

Tôi nghĩ bạn không thể làm điều đó vì Id là duy nhất bạn phải sử dụng nó cho một yếu tố. Bạn có thể sử dụng lớp cho mục đích


1

<div id="one">first text for one</div>
<div id="one">second text for one</div>

var ids = document.getElementById('one');

id chỉ chứa phần tử div đầu tiên. Vì vậy, ngay cả khi có nhiều phần tử có cùng id, đối tượng tài liệu sẽ chỉ trả về kết quả khớp đầu tiên.


0

Không, ID phải là duy nhất. Bạn có thể sử dụng các lớp cho mục đích đó

<div class="a" /><div class="a b" /><span class="a" />

div.a {font: ...;}
/* or just: */
.a {prop: value;}

0

Có thể có nhiều hơn một học sinh trong một lớp có cùng Roll / Id không? Trong idthuộc tính HTML là như vậy. Bạn có thể sử dụng cùng một lớp cho họ. ví dụ:

<div class="a b c"></div>
<div class="a b c d"></div>

Và như thế.


0

Thông thường, tốt hơn là không sử dụng cùng một ID nhiều lần trong một trang html. Thậm chí, có thể sử dụng cùng một ID nhiều lần trong một trang. Tuy nhiên, khi bạn sử dụng ID như một phần của URI / URL như dưới đây:

https://en.wikipedia.org/wiki/FIFA_World_Cup#2015_FIFA_corruption_case

Và nếu ID ('2015_FIFA_corruption_case') chỉ được sử dụng cho một yếu tố (span) trong trang web:

<span class="mw-headline" id="2015_FIFA_corruption_case">2015 FIFA corruption case</span>

Sẽ không có vấn đề gì. Ngược lại, cùng một ID tồn tại ở nhiều nơi, trình duyệt sẽ bị nhầm lẫn.


0

Vâng, họ có thể.

Tôi không biết nếu tất cả các anwers này đã lỗi thời, nhưng chỉ cần mở youtube và kiểm tra html. Hãy thử kiểm tra các video được đề xuất, bạn sẽ thấy rằng tất cả chúng đều có cùng một Id và cấu trúc lặp lại như sau:

<span id="video-title" class="style-scope ytd-compact-radio-renderer" title="Mix - LARA TACTICAL">
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.