Становятся ли элементы дерева DOM с идентификаторами глобальными переменными?

Работая над идеей простой оболочки HTMLElement, я наткнулся на следующее для Internet Explorer и Chrome :

Для данного HTMLElement с идентификатором в дереве DOM можно извлечь div, используя его идентификатор в качестве имени переменной. Так что для div как

some text

в Internet Explorer 8 и Chrome вы можете сделать:

alert(example.innerHTML); //=> 'some text'

или

alert(window['example'].innerHTML); //=> 'some text'

Итак, означает ли это , что каждый элемент в дереве DOM преобразуется в переменную в глобальном пространстве имен? И значит ли это, что можно использовать это в качестве замены для метода getElementById в этих браузерах?

вопрос задан 8.08.2010
KooiInc
78093 репутация

4 ответов


  • 350 рейтинг

    Предполагается, что «именованные элементы» добавляются в качестве очевидных свойств объекта document. Это действительно плохая идея, поскольку она позволяет именам элементов конфликтовать с реальными свойствами document.

    IE усугубил ситуацию, добавив именованные элементы в качестве свойств объекта window. Это вдвойне плохо, так как теперь вы должны избегать именования ваших элементов после того, как какой-либо элемент объекта document или window, который вы (или любой другой библиотечный код в вашем проекте) могут захотеть использовать.

    Это также означает, что эти элементы видны как глобальные переменные. К счастью, в этом случае любые реальные глобальные объявления var или function в вашем коде затеняют их, поэтому вам не нужно так сильно беспокоиться об именовании здесь, но если вы попытаетесь сделать присвоение глобальной переменной с конфликтующим именем, и вы забудете чтобы объявить его var, вы получите ошибку в IE, когда он попытается присвоить значение самому элементу.

    Обычно считается плохой практикой опускать var, а также полагаться на то, что именованные элементы видны в window или как глобальные. Придерживайтесь document.getElementById, который более широко поддерживается и менее неоднозначен. Вы можете написать тривиальную функцию-обертку с более коротким именем, если вам не нравится печатать. В любом случае, нет смысла использовать кеш поиска идентификатора к элементу, потому что браузеры обычно оптимизируют вызов getElementById, чтобы в любом случае использовать быстрый поиск; все, что вы получаете, это проблемы, когда элементы изменяются id или добавляются / удаляются из документа.

    Opera скопировала IE, затем присоединился WebKit, и теперь как ранее нестандартная практика размещения именованных элементов в свойствах document, так и ранее применявшаяся только в IE практика размещения их в window являются , т.е. Подход заключается в том, чтобы документировать и стандартизировать каждую ужасную практику, навязанную нам авторами браузера, что делает их частью сети навсегда. Поэтому Firefox 4 также будет поддерживать это.

    Что такое «именованные элементы»? Все, что с id, и все, что с name, используется для «идентификации» целей: то есть формы, изображения, якоря и некоторые другие, но не другие несвязанные экземпляры атрибута name, такие как имена элементов управления в полях ввода формы, имена параметров в или тип метаданных в

    . «Идентификация» name - это те, которых следует избегать в пользу id.

    ответ дан bobince, с репутацией 433365, 8.08.2010
  • 39 рейтинг

    Как упоминалось в предыдущем ответе, это поведение называется именованным доступом к объекту окна . Значение атрибута name для некоторых элементов и значение атрибута id для всех элементов становятся доступными в качестве свойств глобального объекта window. Они известны как именованные элементы. Поскольку window является глобальным объектом в браузере, каждый именованный элемент будет доступен как глобальная переменная.

    Первоначально он был добавлен Internet Explorer и в конечном итоге был реализован всеми другими браузерами просто для совместимости с сайтами, которые зависят от этого поведения. Интересно, что Gecko (движок рендеринга Firefox) предпочел реализовать это только в режиме quirks , тогда как другие движки рендеринга оставили его в стандартном режиме.

    Однако, начиная с Firefox 14, Firefox теперь поддерживает именованный доступ к объекту window в стандартном режиме. Почему они изменили это? Оказывается, есть еще много сайтов, которые полагаются на эту функциональность в стандартном режиме. Microsoft даже выпустила маркетинговую демоверсию , которая не позволила демоверсии работать в Firefox.

    Webkit недавно рассмотрел противоположность , оставив именованный доступ к объекту window только в режиме причуд. Они решили против этого по той же причине, что и Геккон.

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

    Почему? В этой статье можно подвести итог многим рассуждениям о том, почему глобальные переменные являются плохими . Проще говоря, наличие множества дополнительных глобальных переменных приводит к большему количеству ошибок. Допустим, вы случайно набрали имя var и случайно набрали id узла DOM, СЮРПРИЗ!

    Кроме того, несмотря на стандартизацию, в реализациях браузеров именованного доступа все еще остается довольно много несоответствий.

    • IE неправильно делает значение атрибута name доступным для элементов формы (input, select и т. Д.).
    • Gecko и Webkit по ошибке не делают тегов доступными через их атрибут name.
    • Gecko неправильно обрабатывает несколько именованных элементов с одинаковыми именами (вместо массива ссылок возвращает ссылку на один узел).

    И я уверен, что это еще не все, если вы попытаетесь использовать именованный доступ в крайних случаях.

    Как упоминалось в других ответах, используйте document.getElementById, чтобы получить ссылку на узел DOM по его id. Если вам нужно получить ссылку на узел по его атрибуту name, используйте document.querySelectorAll.

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

    Если вам интересно, я расскажу об этом более подробно в моем блоге - https: // www. tjvantoll. com / 2012/07/19 / dom-element-reference-as-global-variable / .

    ответ дан TJ VanToll, с репутацией 10501, 27.07.2012
  • 18 рейтинг

    Вы должны придерживаться getElementById() в этих случаях, например:

    document.getElementById('example').innerHTML
    

    IE любит смешивать элементы с атрибутами name, и , ID в глобальном пространстве имен, поэтому лучше всего четко указать, что вы пытаетесь получить.

    ответ дан Nick Craver, с репутацией 520537, 8.08.2010
  • 3 рейтинг

    Да, они делают.

    Протестировано в Chrome 55, Firefox 50, IE 11, IE Edge 14 и Safari 10
    со следующим примером:

    
    
    
    
    
    
    Hello World!

    http: // jsbin. ком / mahobinopa / редактировать? HTML, вывод

    ответ дан qff, с репутацией 2616, 23.12.2016