Неуникальные идентификаторы на странице, разрешенные в веб-компонентах

#javascript #dom #web-component

#javascript #dom #веб-компонент

Вопрос:

Разрешены ли неуникальные идентификаторы элементов DOM в веб-компонентах? Я понимаю, что они разрешены в разных документах, но я сталкиваюсь с этой проблемой на youtube.com . В частности, все элементы боковой панели имеют идентификатор ‘endpoint’, и каждый элемент имеет одинаковый ownerDocument (window.document)

Комментарии:

1. Они «разрешены» в том смысле, что браузер справится с этим, но они не будут работать должным образом.

2. id атрибуты должны быть уникальными для каждого документа. Если ваши веб-компоненты используют теневой dom, то внутри этого теневого dom вы можете использовать идентификаторы, которые также встречаются в документе (поскольку вы не можете запрашивать теневой dom извне), но, учитывая, что ваш веб-компонент полностью контролирует свой собственный контент, он уже должен точно знать, где находится теневой dom.элементы, к которым они должны получить доступ, являются. Нет необходимости в выборе запроса внутри теневого dom, создайте свой теневой dom, используя обычные функции api узла, и кэшируйте их в области видимости веб-компонента.

3. Неверно. Повторяющиеся идентификаторы действительны с самых ранних дней Internet Explorer, когда он создавал глобальные переменные для всех значений идентификаторов. Все производители браузеров скопировали это поведение много месяцев назад, потому что когда-то Microsoft владела 90% рынка браузеров, и все браузеры должны были поддерживать веб-приложения, написанные поверх этого (Microsoft) поведения идентификатора. Сегодня все браузеры, кроме FireFox, по-прежнему создают полностью допустимый глобальный массив идентификаторов для дубликатов IDs. this.shadowRoot.querySelectorAll("#foo") вернет все элементы с одинаковым ID=foo внутри ShadowDOM… но они не будут создавать никаких переменных!

4. Кажется, я не могу найти теневой корень в веб-компонентах на youtube.com и документ. querySelectorAll(‘#endpoint’) выдает мне массив элементов. Можно с уверенностью предположить, что теневого корня нет, и youtube просто игнорирует уникальность идентификатора, заданную dom.spec.whatwg.org/#concept-id ?

5.Да, документ. querySelector/getElementById запрашивает основной DOM, он не может запрашивать shadowRoots

Ответ №1:

YouTube использует Polymer.js для создания своих собственных веб-компонентов, которые имеют свой собственный ShadowDOM. Если вы следите за элементами в DevTools, вы увидите разные имена тегов и множество одинаковых идентификаторов из-за того, что многие компоненты содержат ShadowDOM.

Лучше всего настроить таргетинг на элемент с их тегом, используя:

 document.getElementsByTagName('ytd-stupidVariableName-here')
  

В противном случае попробуйте объединить имена классов и идентификаторы, чтобы найти именно тот элемент, который вам нужен.