Существует ли спецификация того, что идентификатор элементов должен быть глобальным?

Если у меня есть <div id='a'> в Chrome, то в javascript я могу сделать a.stuff() (он как будто a является глобальной переменной).

Однако это не работает с FireFox - мне нужно будет использовать document.getElementById('a').

Что такое правильное поведение здесь? (в соответствии с спецификациями W3)

Также меня интересует, как Chrome решит двусмысленность, если у меня есть div с id a, но у меня есть глобальная переменная, называемая a тоже в моем script. Является ли поведение случайным и жестоким?

И как будет преобразован элемент с id, состоящий из дефиса ( "-" ), colons ( ":" ) и периодов ( "." ) (хорошо, я знаю, к ним можно получить доступ с помощью document.getElementById, но как браузер переводит его в глобальную переменную, которая их представляла)

Ответ 1

Это зависит от того, какую спецификацию вы читаете.:)

Это поведение не описывается спецификацией HTML4 (cf, http://www.w3.org/TR/1999/REC-html401-19991224/struct/global.html#adef-id и http://www.w3.org/TR/1999/REC-html401-19991224/types.html#type-name). Однако он был введен Internet Explorer и затем скопирован в другие основные браузеры для обеспечения совместимости. FireFox также отображает это поведение, но только в режиме quirks (и даже тогда его реализация кажется ошибочной).

Спецификация HTML WHATWG в настоящее время требует этого поведения, но есть ошибка , требующая его удаления.

Независимо от соответствия спецификации использование глобального пространства имен (т.е. window) для кода приложения обычно считается плохим. Рассмотрим ссылки на идентификаторы элементов, используя методы удобства document.getElementById() или jQuery (например, $("#a")) и используя переменные с расширенной функциональностью, чтобы избежать ввода новых переменных в глобальное пространство имен.

Более длинное обсуждение этого поведения в списке рассылки WHATWG.

Ответ 2

С самых ранних дней IE создал глобальные переменные, которые ссылаются на элементы по их имени или значению атрибута id. Это никогда не было хорошей идеей, но было скопировано другими браузерами, чтобы быть совместимым с сайтами, созданными для IE.

Это плохая идея, ее нельзя копировать или использовать.

Изменить

Чтобы ответить на дополнительные вопросы:

... как Chrome решит двусмысленность, если у меня есть div с id a но имеют глобальную переменную, называемую тоже в моем script.

В IE (который ввел это поведение), если глобальная переменная объявлена ​​с тем же именем, что и идентификатор элемента или имя, он будет принимать на себя ответственность. Однако незаявленные глобальные переменные не работают. Это не займет много времени, чтобы проверить это в Chrome (у меня есть, но я не дам вам ответа).

И как бы элемент с идентификатором состоящий из дефиса ( "-" ), двоеточия ( ":" ), а периоды ( "." ) будут переведены (хорошо, я знаю, к ним можно получить доступ document.getElementById, но как браузер переводит его в глобальная переменная, представляющая их)

Точно так же, как любое имя свойства объекта, которое не является допустимым идентификатором - обозначение квадратной скобки (то есть окно ['name-or-id']).

Ответ 3

Технически, этот вопрос - мнение, но это хороший вопрос.

IE делает это также, и это вызвало головные боли для некоторых.

Правила присвоения имен переменных в JavaScript и идентификаторы в HTML различны. Я не вижу, как это хорошо.

Например, на этой странице есть элемент с идентификатором "notify-container". Это не действительное имя JavaScript вообще.

Кроме того, когда эти имена связаны? Если встроенный script объявляет переменную, а затем элемент появляется позже, у которого есть приоритет?

Это не может быть согласовано.

Ответ 4

Я думаю, что document.getElementById поддерживается большинством браузеров до сих пор. Его лучше и безопаснее использовать этот.

Ответ 5

Самое худшее в использовании элементов таким образом состоит в том, что они могут сломаться в любое время, если будет введен новый API с таким же именем в глобальной области.

Например, если у вас было это до добавления Performance API

<p id="performance"></p>
<script>
    performance.innerHTML = "You're doing great"
</script>

Затем этот фрагмент кода теперь перестанет работать в последних браузерах, который реализовал API производительности как глобальный объект performance.