Чи може кілька різних елементів HTML мати однаковий ідентифікатор, якщо вони різні елементи?


139

Чи дійсний такий сценарій ?:

div#foo
span#foo
a#foo

23
Хоча іноді це можливо, це ніколи не діє.
Пол Кріссі

2
Враховуючи все вищесказане, варто відзначити, що, ймовірно, в документі зі змістом, створеним користувачем-агентом (можливі рамки, mv *, реагувати, полімер ...) трапляються кілька ідентичних ідентифікаторів. Ось якщо хтось цікавився, чому на дуже професійному погляді XYZ-сайт переповнений такою недоброю практикою .
Лукаш Матісяк

Відповіді:


180

Немає.

Ідентифікатори елементів повинні бути унікальними у всьому документі.


85
Які наслідки цього не робити?
corsiKa

16
@corsiKa наслідком є ​​невизначена поведінка, наприклад, що повертає document.getElementById ("# foo") або $ ("# foo"), коли є кілька # foos? У вас виникнуть проблеми з можливістю роботи з цими елементами від JS, передайте їх як селектори в бібліотеки / API / Flash тощо.
mrooney

76
Це неправильно. Цілком можливо мати кілька елементів з однаковим ідентифікатором. Це, як правило, не найкраща практика , але вона має своєрідне використання. Всі, здається, цитують, як би працювали селектори, добре, якщо ви збираєтеся знати, що у вас будуть конфліктні ідентифікатори, ви використовуєте селекторів з батьком, де ідентифікатори під батьком були б унікальними. наприклад $('div#car span#size)і $('div#truck span#size').
BJury

18
навіщо навіть використовувати кілька подібних ідентифікаторів, коли для цього ви отримали клас?
Макс Ярі

6
Так, кілька ідентифікаторів на практиці можна замінити використанням класів. Однак класи призначені для застосування стилів, не ідентифікуючи елементів, роблячи область імен набагато ширшими і, отже, ймовірно, що вони збігаються. Особливо якщо використовувати сторонні бібліотеки. Ідентифікатор як "ідентифікатор" не розраховується на множення, тому явно потрібно щось середнє. Практичне використання - це компонентизація розділів сторінки / дому в окремі логічні одиниці. Звідси потрібно використовувати (принаймні) двошарову ідентифікацію.
Ален Силяк

85

Я думаю, що є різниця між тим, чи МОЖЕ БУТИ бути унікальним або ОБОВ'ЯЗКОВО бути унікальним (тобто застосовується веб-браузерами).

Чи повинні посвідчення особи бути унікальними? ТАК.

Чи повинні бути ідентифікатори унікальними? НІ, принаймні IE і FireFox дозволяють багатьом елементам мати однаковий ідентифікатор.


6
Так само і Chrome (v22 на момент написання цього коментаря). : D
omninonsense

27
Відповідно до специфікації , це ОБОВ'ЯЗКОВО, а не ДОБРЕ. (Це все ще працює в більшості браузерів? Так. Чи дійсний HTML? Ні. getElementByIdРезультат у таких випадках undefinedозначає, що немає способу сказати, як браузер міг обрати його.)
leo

2
@leo, однак, це справжній світ, де браузери не повністю відповідають стандартам. У цьому випадку це може бути хорошою справою, оскільки немає підстав застосовувати унікальні ідентифікатори.
BJury

1
У HTML5 специфікація getElementByIdнасправді визначає, що перший елемент із заданим ідентифікатором повинен бути повернутий (саме так усі браузери в даний час вирішують ситуацію) - докладнішу інформацію див. Нижче.
млці

1
Не плач, використовуй jQuery. @leo
Máxima Alekz

67

Чи можуть кілька елементів мати однаковий ідентифікатор?

Так - незалежно від того, є вони однаковим тегом чи ні, браузери відображатимуть сторінку, навіть якщо кілька елементів мають однаковий ідентифікатор.

Чи дійсний HTML?

Ні. Це все ще стосується специфікації HTML 5.1 . Однак, spec також говорить, що getElementById повинен повернути перший елемент із заданим ідентифікатором , роблячи поведінку не визначеною у випадку недійсного документа.

Які наслідки цього типу недійсного HTML?

Більшість браузерів (якщо не всі) вибрали і все ж вибирають перший елемент із заданим ідентифікатором під час виклику getElementById. Більшість бібліотек, які знаходять елементи за ідентифікатором, успадковують цю поведінку. Більшість браузерів (якщо не всі) також застосовують стилі, призначені id-селекторами (наприклад #myid) до всіх елементів із вказаним ідентифікатором. Якщо це те, що ви очікуєте і маєте намір, то непередбачуваних наслідків немає. Якщо ви очікуєте / маєте намір щось інше (наприклад, для повернення всіх елементів із цим ідентифікатором або для стилю, що застосовується лише до одного елемента), ваші очікування не виправдаються, і будь-яка функція, що спирається на ці очікування, не вийде.

Деякі бібліотеки JavaScript дійсно є очікування, що не зустрічалися , коли кілька елементів мають однаковий ідентифікатор (див коментар wootscootinboogie в про d3.js)

Висновок

Найкраще дотримуватися стандартів, але якщо ви знаєте, що ваш код працює так, як очікувалося в ваших поточних умовах, і ці ідентифікатори використовуються передбачуваним / ремонтованим способом, то є лише 2 практичні причини цього не робити:

  1. Щоб уникнути випадків помилки, і одна з використовуваних вами бібліотек насправді не працює, коли кілька елементів мають однаковий ідентифікатор.
  2. Для підтримки сумісності вашого веб-сайту / програми з бібліотеками чи службами (або розробниками!) У майбутньому ви можете зіткнутись, які не працюватимуть, коли кілька елементів мають однаковий ідентифікатор - що є розумною можливістю, оскільки це технічно не є дійсним HTML.

Сила твоя!


Відмінна відповідь. завжди краще, якщо ви дотримуєтесь стандартів.
EKanadily

25

Навіть якщо елементи різного типу, це може викликати у вас серйозні проблеми ...

Припустимо, у вас є 3 кнопки з однаковим ідентифікатором:

<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');
    });
});

Що б ви очікували? Щоб кожна натиснута кнопка виконувала налаштування обробника подій кліку за допомогою jQuery. На жаль, цього не станеться. ТІЛЬКИ перша кнопка викликає обробник кліків. Інші 2 при натисканні нічого не роблять. Наче вони зовсім не були кнопками!

Так завжди призначати різні IDsдля HTMLелементів. Це дозволить вам захиститися від дивних речей. :)

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

Тепер, якщо ви хочете, щоб обробник подій клацання запускався при натисканні будь-якої кнопки, він буде спрацьовувати чудово, якщо ви зміните селектор в коді jQuery, щоб використовувати CSSклас, застосований до них так:

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

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

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

що робити, якщо у мене є "#content", на який я вже посилався в змінній, і # my-div #content, який у мене є лише на кілька моментів, після чого я видаляю посилається вузол і забуваю його змінну, після чого # div #content виконує myDiv.outerHTML = myDiv.innerHTML для заміни оригіналу. Це заощаджує необхідність копіювати всі стилі та вміст #content в #decoy і робити те саме. Це має сенс робити переходи.
Дмитро

Це означає, що, навіть якщо я використовую "додати" для додавання декількох елементів одного і того ж ідентифікатора, DOM вважає реальним лише перший елемент, в ідеалі 1 ID = 1 елемент
Karan Kaw

22

№ два елементи з однаковим ідентифікатором недійсні. Ідентифікатори унікальні, якщо ви хочете зробити щось подібне, використовуйте клас. Не забувайте, що елементи можуть мати кілька класів, використовуючи простір як деліметр:

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

12

В офіційній специфікації для HTML зазначено, що теги id повинні бути унікальними І офіційна специфікація також говорить, що якщо візуалізація може бути завершена, вона повинна (тобто в HTML немає такого поняття, як "помилки", лише "недійсний" HTML). Отже, далі - як ідентифікаційні теги насправді працюють на практиці . Усі вони недійсні , але все ще працюють:

Це:

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

Здійснює відмінний показник у всіх браузерах. Однак document.getElementById повертає лише об'єкт, а не масив; ви зможете вибрати лише перший div через тег id. Якщо ви повинні змінити ідентифікатор першого div за допомогою JavaScript, другий ідентифікатор буде доступний за допомогою document.getElementById (тестується на Chrome, FireFox та IE11). Ви все ще можете вибрати div за допомогою інших методів вибору, і його властивість id буде повернено правильно.

Зверніть увагу, що це вище питання відкриває потенційну вразливість безпеки на сайтах, що рендерують SVG-зображення, оскільки SVG може містити елементи DOM, а також ідентифікатор тегів на них (дозволяє переадресація DOM скрипту через завантажені зображення). Поки SVG розміщений у DOM перед тим, як елемент його замінить, зображення отримає всі події JavaScript, призначені для іншого елемента.

Наразі це питання не на радіолокації нікого, наскільки я знаю, але це реально.

Це:

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

Також добре відображається у всіх браузерах. Однак використовується лише перший ідентифікатор, який ви визначаєте таким чином, якщо ви спробували document.getElementById ('унікальний-також'); в наведеному вище прикладі, ви б повернулися нуль (перевірено на Chrome, FireFox і IE11).

Це:

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

Також добре відображається у всіх браузерах, однак, на відміну від тегів класу, які можна розділити пробілом, тег id дозволяє пробіли, тож ідентифікатор вищевказаного елемента насправді є "унікальним унікальним двома" та запитує dom для "унікального" або "унікальний-два" в ізоляції повертає нуль, якщо інше не визначено в іншому місці DOM (тестовано на Chrome, FireFox та IE11).


1
"тег id дозволяє пробіли" - Хоча, згідно з специфікацією , "Значення не повинно містити символів пробілу."
MrWhite

Я згоден. Однак є специфікація, і є, як працюють браузери. Браузери історично трактують специфікацію як щось із цілей, але не суворо ставляться до багатьох предметів. Я думаю, що вони роблять це, бо якби вони зустріли специфікацію, це зламало б багато існуючих сайтів чи щось таке. Я зверху зазначу, що хоча ці речі працюють, вони недійсні.
Нік Стіл

5

Відповідь SLaks правильна, але в якості доповнення зауважте, що специфікації x / html вказують, що всі ідентифікатори повинні бути унікальними в (одному) html-документі . Хоча це не саме те, про що запитували, можуть бути дійсні випадки, коли один і той же ідентифікатор додається до різних об'єктів на кількох сторінках.

Приклад:

(подається сучасним браузерам) стаття # main-content { styled one way }
(подається у спадщину) div # main-content { styled other way }

Напевно, антипатерн. Просто виїхавши звідси, як захисник диявола.


1
Гарна думка. Хоча динамічно генерований вміст, який повинен бути вставлений на іншу сторінку, повинен взагалі уникати ідентифікаторів. Ідентифікатори схожі на глобальні мови в мовах програмування, ви можете їх використовувати, і є дійсні випадки, коли це хороший хакер, який спрощує речі. Приємною практикою вважати робити речі правильно, перш ніж робити хакі.
psycho brm

4

І для чого це варто, на Chrome 26.0.1410.65, Firefox 19.0.2 і Safari 6.0.3 принаймні, якщо у вас є кілька елементів з однаковим ідентифікатором, селектори jquery (принаймні) повернуть перший елемент із цим ідентифікатором.

напр

<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що, звичайно, не змінює факту, що він недійсний.
Кевін Б

Можливо, ця відповідь правдива, я це кажу з досвіду.
Діб’яншу Джайсваль

4

Добре, використовуючи валідатор HTML на w3.org , характерний для HTML5, ідентифікатори повинні бути унікальними

Розглянемо наступне ...

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

Висновок:

В будь-якому випадку (той самий тип елемента або інший тип елемента), якщо ідентифікатор використовується більше, ніж один раз, він не вважається допустимим HTML5.


2

Ми можемо використовувати ім’я класу замість ідентифікатора. html id мають бути унікальними, але класи - ні. при отриманні даних за допомогою імені класу можна зменшити кількість рядків коду у ваших js-файлах.

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


1

Я думаю, ви не можете цього зробити, тому що Id унікальний, ви повинні використовувати його для одного елемента. Ви можете використовувати клас за ціллю


1

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

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

Ідентифікатори містять лише перший елемент div. Тож навіть якщо є кілька елементів з однаковим ідентифікатором, об'єкт документа поверне лише перший збіг.


0

Ні, посвідчення особи повинні бути унікальними. Для цього можна використовувати заняття

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

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

0

Чи можливо мати більше одного учня в класі, який має той самий Roll / Id ні? У HTML idатрибут такий. Ви можете використовувати для них один і той же клас. наприклад:

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

І так далі.


0

Зазвичай, краще не використовувати один і той же ідентифікатор кілька разів на html-сторінці. Незважаючи на це, на сторінці можна багато разів використовувати одне ідентичне ідентифікатор. Однак коли ви використовуєте ідентифікатор як частину URI / URL, як показано нижче:

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

І якщо ID ('2015_FIFA_corrup_case') використовується лише для одного (span) елемента на веб-сторінці:

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

Проблеми не було б. Навпаки, той самий ідентифікатор існує в більш ніж одному місці, браузер буде заплутаний.


0

Так вони можуть.

Я не знаю, чи застаріли всі ці анвери, але просто відкрийте ютуб і перевірте html. Спробуйте ознайомитись із запропонованими відео, ви побачите, що всі вони мають однакову ідентифікаційну та повторювану структуру:

<span id="video-title" class="style-scope ytd-compact-radio-renderer" title="Mix - LARA TACTICAL">
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.