Почему бы нам просто не использовать идентификаторы элементов в качестве идентификаторов в JavaScript?
Все браузеры, с которыми я пришел работать, позволяют получить доступ к элементу с помощью id="myDiv"
, просто написав:
myDiv
Смотрите здесь: http://jsfiddle.net/L91q54Lt/
Во всяком случае, этот метод, как представляется, довольно плохо документирован, и на самом деле источники, с которыми я сталкиваюсь, даже не упоминают об этом, а вместо этого предполагают, что использовать
document.getElementById("myDiv")
или, возможно,
document.querySelector("#myDiv")
для доступа к элементу DOM, даже если его идентификатор известен заранее (т.е. не вычисляется во время выполнения). Я могу сказать, что последние подходы имеют преимущество в обеспечении безопасности кода, если кто-то непреднамеренно пытается переопределить myDiv
в более широкой области (не такая блестящая идея, хотя...), перезаписывает ее с каким-то другим значением и продолжается без заметив столкновение.
Но что это? Есть ли проблемы в использовании короткой формы, отличной от кода, или чего еще я здесь не вижу?
Ответы
Ответ 1
Во всяком случае, этот метод, похоже, довольно плохо документирован, и на самом деле источники, с которыми я сталкиваюсь, даже не упоминают [...]
Опора на неявно объявленные глобальные переменные в сторону, отсутствие документации - отличная причина не использовать ее.
Явное продвижение значений id
в глобальные переменные не соответствует стандартам (спецификация HTML5 для атрибута ID не упоминает об этом) и, следовательно, вы не должны предполагать, что будущие браузеры его реализуют.
EDIT: Оказывается, это поведение соответствует стандартам. В HTML5 window
должен поддерживать доступ к свойствам "Именованные элементы":
Именованные объекты с именем name для целей вышеуказанного алгоритма - это те, которые:
- дочерние контексты просмотра активного документа, имя которого - имя,
- a, апплет, область, вставка, форма, frameset, img или элементы объекта, которые имеют атрибут содержимого имени, значение которого является именем, или
- HTML-элементы, у которых есть атрибут содержимого id, значение которого является именем.
Источник: Спецификация HTML 5, "Именованный доступ к объекту окна" , акцент мой.
Исходя из этого, соблюдение стандартов не является основанием для предотвращения этого шаблона. Однако сама спецификация не рекомендует использовать ее:
Как правило, полагаясь на это, вы получите хрупкий код. Который Идентификация конечного отображения в этот API может меняться со временем, поскольку новые функции например, к веб-платформе. Вместо этого используйте document.getElementById()
или document.querySelector()
.
Ответ 2
Отличный вопрос. Как, вероятно, Эйнштейн не сказал, все должно быть как можно проще и проще.
последние подходы имеют преимущество, заключающееся в том, чтобы держать код в безопасности, если кто-то непреднамеренно пытается переопределить myDiv в более широкой области (не такая блестящая идея, хотя...), перезаписывает ее с некоторым разным значением и продолжается, не замечая столкновения
Это главная причина, почему это плохая идея, и ее достаточно. Надежные глобальные переменные. Они могут быть перезаписаны в любое время любым script, который заканчивается на странице.
В дополнение к этому просто ввод текста myDiv
не является "короткой формой" document.getElementById()
. Его ссылка на глобальную переменную. document.getElementById()
будет с радостью возвращать null
, если элемент не существует, в то время как попытка получить доступ к несуществующей глобальной переменной вызовет ошибку ссылки, поэтому вам необходимо обернуть ссылки на глобальные блок try/catch будет безопасным.
Это одна из причин, почему jQuery настолько популярен: если вы делаете $("#myDiv").remove()
, и нет элемента с идентификатором myDiv
, ошибка не будет выдана - код просто молчат ничего, что часто именно то, что вы хотите, когда выполняете манипуляции с DOM.
Ответ 3
Есть несколько причин:
Вы не хотите, чтобы ваш код и разметка были связаны.
Используя определенный вызов для доступа к div, вам не нужно беспокоиться о повреждении глобального пространства. Добавьте библиотеку, которая объявляет myDiv
в глобальном пространстве, и вы окажетесь в мире боли, который будет трудно исправить.
Вы можете получить доступ к элементам по идентификатору, которые не являются частью DOM
Они могут быть фрагментом, фреймом или элементом, который был отсоединен и еще не присоединен к DOM.
РЕДАКТИРОВАТЬ: Пример доступа к неприкрепленным элементам по ID
var frag = document.createDocumentFragment();
var span = document.createElement("span");
span.id = "span-test";
frag.appendChild(span);
var span2 = frag.getElementById("span-test");
alert(span === span2);
Ответ 4
В моем случае у меня был iframe внутри моей страницы. Меня смутил атрибут id
против атрибута name
, оба из которых влияли на переменную с именем inner_iframe
, доступную из window
!
-
Если бы я использовал только атрибут id, например id="inner_iframe"
, window.inner_iframe
- это HTMLIFrameElement
. Свойства включают inner_iframe.contentDocument
и inner_iframe.contentWindow
как описано здесь *
- В этом случае я предполагаю, что переменная появляется в
window
по причине, указанной @joew в принятом ответе: HTML-элементы, имеющие атрибут содержимого id, значением которого является name
-
Если бы я использовал только атрибут name, например name="inner_iframe"
то window.inner_iframe
- это "рамка", или "объект окна". contentWindow
, поэтому атрибут name inner_iframe не имеет свойств contentDocument
или contentWindow
.
- Я предполагаю, что переменная
inner_iframe
появляется в window
по причине, указанной @joew в принятом ответе дочерние контексты просмотра активного документа, имя которого name
- Если я использовал оба
name
и id
признаки, и я дал оба атрибута такое же значение name="inner_iframe" id="inner-iframe"
; атрибут name
превзошел/заточил атрибут id
; У меня остался "объект окна", а не HTMLIFrameElement
!
Поэтому я хочу быть осторожным с двусмысленностью; конфликт между атрибутами name
и id
в одном и том же объекте с двумя разными API: это просто особый случай, когда неявное поведение и привязка к переменной окна могут сбить вас с толку.
* (и только если <script>
был загружен после/ниже <iframe>
в HTML, или <script>
ждал до window.onload
прежде чем пытаться получить доступ по атрибуту id)
** это отличие "фрейма" от элемента DOM описано в документации Mozilla как:
Каждый элемент в псевдомассиве window.frames представляет объект окна, соответствующий заданному элементу или содержимому, а не элемент DOM кадра (i) (т.е. Window.frames [0] - это то же самое, что document.getElementsByTagName("iframe") ) [0].contentWindow).