Могут ли несколько элементов HTML иметь одинаковый идентификатор, если они относятся к разным типам элементов? Верен ли такой сценарий? Например:
div#foo
span#foo
a#foo
Могут ли несколько элементов HTML иметь одинаковый идентификатор, если они относятся к разным типам элементов? Верен ли такой сценарий? Например:
div#foo
span#foo
a#foo
Ответы:
Нет.
Идентификаторы элементов должны быть уникальными в пределах всего документа.
$('div#car span#size)
и $('div#truck span#size')
.
Я думаю, есть разница между тем, ДОЛЖНО ли что-то быть уникальным или ДОЛЖНО быть уникальным (т. Е. Обеспечивается веб-браузерами).
Должны ли идентификаторы быть уникальными? ДА.
Идентификаторы должны быть уникальными? НЕТ, по крайней мере IE и FireFox позволяют нескольким элементам иметь один и тот же идентификатор.
getElementById
в таких случаях результатом является то undefined
, что невозможно определить, как браузер может решить его обрабатывать.)
getElementById
самом деле определяет, что должен быть возвращен первый элемент с данным идентификатором (именно так все браузеры в настоящее время обрабатывают ситуацию) - подробнее см. Мой ответ ниже.
Могут ли несколько элементов иметь одинаковый идентификатор?
Да - независимо от того, являются ли они одним и тем же тегом, браузеры будут отображать страницу, даже если несколько элементов имеют одинаковый идентификатор.
Это действительный HTML?
Нет. Это все еще верно для спецификации HTML 5.1 . Однако в спецификации также говорится, что getElementById
должен возвращать первый элемент с данным идентификатором , что делает поведение не неопределенным в случае недопустимого документа.
Каковы последствия этого типа недействительного HTML?
Большинство (если не все) браузеры выбрали и все еще выбирают первый элемент с заданным идентификатором при вызове getElementById
. Большинство библиотек, которые находят элементы по идентификатору, наследуют это поведение. Большинство (если не все) браузеры также применяют стили, назначенные селекторами идентификаторов (например #myid
), ко всем элементам с указанным идентификатором. Если это то, чего вы ожидаете и намерены, то непредвиденных последствий не будет. Если вы ожидаете / намереваетесь что-то еще (например, чтобы все элементы с этим идентификатором были возвращены, или чтобы стиль применялся только к одному элементу), ваши ожидания не будут выполнены, и любая функция, основанная на этих ожиданиях, потерпит неудачу.
Некоторые библиотеки javascript действительно имеют ожидания, которые не оправдываются, когда несколько элементов имеют одинаковый идентификатор (см . Комментарий wootscootinboogie о d3.js)
Вывод
Лучше придерживаться стандартов, но если вы знаете, что ваш код работает должным образом в ваших текущих средах, и эти идентификаторы используются предсказуемым / поддерживаемым способом, то есть только две практические причины не делать этого:
Сила твоя!
Даже если элементы бывают разных типов, это может вызвать у вас серьезные проблемы ...
Предположим, у вас есть 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');
});
});
Официальная спецификация для HTML гласит, что теги идентификаторов должны быть уникальными, И в официальной спецификации также говорится, что если рендеринг может быть завершен, он должен (т.е. в HTML нет такой вещи, как «ошибки», только «недействительный» HTML). Итак, ниже показано, как теги id работают на практике . Все они недействительны , но работают:
Этот:
<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, а также теги id на них (разрешает перенаправление DOM сценария через загруженные изображения). Пока SVG расположен в DOM перед заменяемым элементом, изображение будет получать все события JavaScript, предназначенные для другого элемента.
Насколько я знаю, эта проблема в настоящее время никого не интересует, но она реальна.
Этот:
<div id="unique" id="unique-also">One</div>
Также отлично отображается во всех браузерах. Однако используется только первый идентификатор, который вы определяете таким образом, если вы пробовали document.getElementById ('unique-also'); в приведенном выше примере вам будет возвращено значение null (проверено в Chrome, FireFox и IE11).
Этот:
<div id="unique unique-two">Two</div>
Также отлично отображается во всех браузерах, однако, в отличие от тегов классов, которые могут быть разделены пробелом, тег id допускает пробелы, поэтому идентификатор вышеуказанного элемента фактически равен «unique unique-two» и запрашивает у dom значение «unique» или «unique-two» изолированно возвращает null, если иное не определено где-либо в DOM (проверено в Chrome, FireFox и IE11).
Ответ SLaks правильный, но в качестве дополнения обратите внимание, что в спецификациях x / html указано, что все идентификаторы должны быть уникальными в (одном) html-документе . Хотя это не совсем то, о чем спрашивал оператор, могут быть допустимые случаи, когда один и тот же идентификатор привязан к разным объектам на нескольких страницах.
Пример:
(обслуживается в современных браузерах) article # main-content {в одностороннем стиле }
(используется в устаревших версиях) div # main-content { в другом стиле }
Хотя, наверное, антипаттерн. Просто уйду отсюда как защитник дьявола.
И чего бы это ни стоило, по крайней мере, в 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
конечно, это не меняет того факта, что он недействителен.
Что ж, используя валидатор 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>
... но в 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>
... результат валидатора ...
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.
Да, они могут.
Я не знаю, устарели ли все эти ответы, но просто откройте YouTube и проверьте HTML. Попробуйте просмотреть предложенные видео, вы увидите, что все они имеют одинаковый идентификатор и повторяющуюся структуру, как показано ниже:
<span id="video-title" class="style-scope ytd-compact-radio-renderer" title="Mix - LARA TACTICAL">
<div id="one">first text for one</div>
<div id="one">second text for one</div>
var ids = document.getElementById('one');
идентификаторы содержат только первый элемент 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))
и увидеть все повторяющиеся идентификаторы.
Изменение приведенного выше кода для отображения идентификаторов, повторяющихся более 10 раз, вот список, который он создал
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
Другие сайты, которые используют один и тот же идентификатор более одного раза, включают Amazon.com, ebay.com, Expedia.com, cnn.com.
очевидно, что идентификаторы - это просто еще одна часть метаданных элемента.
getElementById
в значительной степени устарело. Вы можете использовать querySelectorAll
для всех элементов или querySelector
для первого, независимо от селектора, поэтому, если вам нужны все элементы с идентификатором, 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.
И мы видим, что с помощью селекторов мы можем находить разные элементы с одним и тем же идентификатором.
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);
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>0</span></div>
<div class="f"><button type="button" id="foo">+10</button>: <span>0</span></div>
<a>
Теги могут ссылаться на идентификаторы, как в <a href="#foo">
. Щелчок по нему переместит документ к первому элементу с id="foo"
. Точно так же хэш-тег в URL-адресе, который фактически является той же функцией.
<label>
Теги имеют for
атрибут, который указывает, какой элемент они маркируют по идентификатору. Щелчок по метке щелкает / активирует / дает фокус соответствующему элементу. Метка повлияет только на первый элемент с совпадающим идентификатором
В противном случае id
это просто еще один инструмент в вашем наборе инструментов.
Возможно ли, чтобы в классе было более одного ученика с одинаковым номером Roll / Id? В HTML id
атрибут вроде так. Вы можете использовать для них один и тот же класс. например:
<div class="a b c"></div>
<div class="a b c d"></div>
И так далее.
Мы можем использовать имя класса вместо идентификатора. html id должен быть уникальным, а классы - нет. при извлечении данных с использованием имени класса можно уменьшить количество строк кода в ваших файлах js.
$(document).ready(function ()
{
$(".class_name").click(function ()
{
//code
});
});