为什么我们不在JavaScript中使用元素ID作为标识符?

时间:2022-09-20 13:40:50

All browsers I've come to work with allow accessing an element with id="myDiv" by simply writing:

我开始使用的所有浏览器只需编写以下内容即可访问id =“myDiv”的元素:

myDiv

See here: http://jsfiddle.net/L91q54Lt/

见这里:http://jsfiddle.net/L91q54Lt/

Anyway, this method seems to be quite poorly documented, and in fact, the sources I come across don't even give it a mention and instead assume that one would use

无论如何,这种方法似乎很难记录,事实上,我遇到的来源甚至没有提及它,而是假设一个人会使用

document.getElementById("myDiv")

or maybe

或者可能

document.querySelector("#myDiv")

to access a DOM element even when its ID is known in advance (i.e. not calculated at runtime). I can tell that the latter approaches have the advantage of keeping the code safe if someone inadvertedly attempts to redefine myDiv in a wider scope (not such a brilliant idea though...), overwrites it with some different value and goes on without noticing the *.

即使在事先知道其ID(即未在运行时计算)时也访问DOM元素。我可以说,如果有人无意中尝试在更广泛的范围内重新定义myDiv(虽然不是这么好的想法......),后者的方法具有保持代码安全的优点,用一些不同的值覆盖它并继续而没有注意到冲突。

But other that that? Are there any concerns in using the short form above other than code design, or what else am I missing here?

但其他那个呢?除了代码设计之外,使用上面的简短表格是否有任何问题,或者我在这里缺少什么?

3 个解决方案

#1


38  

Anyway, this method seems to be quite poorly documented, and In fact, the sources I come across don't even give it a mention [...]

无论如何,这种方法似乎记录很差,事实上,我遇到的消息来源甚至没有提及[...]

Reliance on implicitly-declared global variables aside, the lack of documentation is a great reason not to use it.

除了隐含声明的全局变量之外,缺乏文档是不使用它的一个重要原因。

The apparent promotion of id values into global variables isn't standards compliant (the HTML5 spec for the ID attribute doesn't mention it) and, therefore, you shouldn't assume future browsers will implement it.

将id值明显提升为全局变量并不符合标准(ID属性的HTML5规范没有提到它),因此,您不应该假设未来的浏览器会实现它。

EDIT: It turns out this behaviour is standards compliant - In HTML5, window should support property access to "Named Elements":

编辑:事实证明这种行为符合标准 - 在HTML5中,窗口应该支持对“命名元素”的属性访问:

Named objects with the name name, for the purposes of the above algorithm, are those that are either:

出于上述算法的目的,具有名称名称的命名对象是:

  • child browsing contexts of the active document whose name is name,
  • 子浏览名称为name的活动文档的上下文
  • a, applet, area, embed, form, frameset, img, or object elements that have a name content attribute whose value is name, or
  • a,applet,area,embed,form,frameset,img或具有名称内容属性,其值为name的对象元素,或者
  • HTML elements that have an id content attribute whose value is name.
  • 具有id内容属性,其值为name的HTML元素。

Source: HTML 5 spec, 'Named access on window object", emphasis mine.

来源:HTML 5规范,'窗口对象上的命名访问',强调我的。

Based on this, standards compliance is not a reason to avoid this pattern. However, the spec itself advises against its use:

基于此,标准合规性不是避免这种模式的理由。但是,规范本身建议不要使用它:

As a general rule, relying on this will lead to brittle code. Which IDs end up mapping to this API can vary over time, as new features are added to the Web platform, for example. Instead of this, use document.getElementById() or document.querySelector().

作为一般规则,依赖于此将导致脆弱的代码。例如,随着新功能添加到Web平台,哪些ID最终映射到此API可能会随时间而变化。而不是这个,使用document.getElementById()或document.querySelector()。

#2


17  

Great question. As Einstein probably didn’t say, things should be as simple as possible, and no simpler.

好问题。正如爱因斯坦可能没有说的那样,事情应尽可能简单,并不简单。

the latter approaches have the advantage of keeping the code safe if someone inadvertedly attempts to redefine myDiv in a wider scope (not such a brilliant idea though...), overwrites it with some different value and goes on without noticing the *

如果有人无意中试图在更广泛的范围内重新定义myDiv(虽然不是这么好的想法......),后一种方法的优点是保持代码安全,用一些不同的值覆盖它并继续而不注意冲突

That’s the main reason why this is a bad idea, and it’s quite enough. Global variables aren’t safe to rely on. They can be overwritten at any time, by any script that ends up running on the page.

这就是为什么这是一个坏主意的主要原因,而且这已经足够了。全局变量不能安全依赖。它们可以随时被任何最终在页面上运行的脚本覆盖。

In addition to that, just typing in myDiv isn’t a “short form” of document.getElementById(). It’s a reference to a global variable.document.getElementById() will happily return null if the element doesn’t exist, whilst attempting to access a non-existent global variable will throw a reference error, so you’d need to wrap your references to the global in a try/catch block to be safe.

除此之外,只输入myDiv不是document.getElementById()的“简短形式”。它是对全局变量的引用。如果元素不存在,则会愉快地返回null,而尝试访问不存在的全局变量将引发引用错误,因此您需要包装引用到try / catch块中的全局是安全的。

This is one reason why jQuery is so popular: if you do $("#myDiv").remove(), and there is no element with an id of myDiv, no error will be thrown — the code will just silently do nothing, which is often exactly what you want when doing DOM manipulation.

这就是为什么jQuery如此受欢迎的一个原因:如果你做$(“#myDiv”)。remove(),并且没有id为myDiv的元素,就不会抛出任何错误 - 代码只会默默地做什么,这通常是您在进行DOM操作时所需要的。

#3


11  

There are a few reasons:

有几个原因:

You don't want your code and your markup that coupled.

您不希望您的代码和标记耦合在一起。

By using a specific call to access a div, you don't have to worry about the global space being corrupted. Add a library that declares myDiv in global space and you're in a world of pain that will be hard to fix.

通过使用特定的调用来访问div,您不必担心全局空间被破坏。添加一个在全局空间中声明myDiv的库,您将陷入一个难以修复的痛苦世界。

You can access elements, by ID, that aren't part of the DOM

您可以按ID访问不属于DOM的元素

They can be in a fragment, a frame, or an element that has been detached and not re-attached to the DOM yet.

它们可以位于片段,框架或已分离但尚未重新附加到DOM的元素中。

EDIT: Example of accessing a non-attached elements by ID

编辑:按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);

#1


38  

Anyway, this method seems to be quite poorly documented, and In fact, the sources I come across don't even give it a mention [...]

无论如何,这种方法似乎记录很差,事实上,我遇到的消息来源甚至没有提及[...]

Reliance on implicitly-declared global variables aside, the lack of documentation is a great reason not to use it.

除了隐含声明的全局变量之外,缺乏文档是不使用它的一个重要原因。

The apparent promotion of id values into global variables isn't standards compliant (the HTML5 spec for the ID attribute doesn't mention it) and, therefore, you shouldn't assume future browsers will implement it.

将id值明显提升为全局变量并不符合标准(ID属性的HTML5规范没有提到它),因此,您不应该假设未来的浏览器会实现它。

EDIT: It turns out this behaviour is standards compliant - In HTML5, window should support property access to "Named Elements":

编辑:事实证明这种行为符合标准 - 在HTML5中,窗口应该支持对“命名元素”的属性访问:

Named objects with the name name, for the purposes of the above algorithm, are those that are either:

出于上述算法的目的,具有名称名称的命名对象是:

  • child browsing contexts of the active document whose name is name,
  • 子浏览名称为name的活动文档的上下文
  • a, applet, area, embed, form, frameset, img, or object elements that have a name content attribute whose value is name, or
  • a,applet,area,embed,form,frameset,img或具有名称内容属性,其值为name的对象元素,或者
  • HTML elements that have an id content attribute whose value is name.
  • 具有id内容属性,其值为name的HTML元素。

Source: HTML 5 spec, 'Named access on window object", emphasis mine.

来源:HTML 5规范,'窗口对象上的命名访问',强调我的。

Based on this, standards compliance is not a reason to avoid this pattern. However, the spec itself advises against its use:

基于此,标准合规性不是避免这种模式的理由。但是,规范本身建议不要使用它:

As a general rule, relying on this will lead to brittle code. Which IDs end up mapping to this API can vary over time, as new features are added to the Web platform, for example. Instead of this, use document.getElementById() or document.querySelector().

作为一般规则,依赖于此将导致脆弱的代码。例如,随着新功能添加到Web平台,哪些ID最终映射到此API可能会随时间而变化。而不是这个,使用document.getElementById()或document.querySelector()。

#2


17  

Great question. As Einstein probably didn’t say, things should be as simple as possible, and no simpler.

好问题。正如爱因斯坦可能没有说的那样,事情应尽可能简单,并不简单。

the latter approaches have the advantage of keeping the code safe if someone inadvertedly attempts to redefine myDiv in a wider scope (not such a brilliant idea though...), overwrites it with some different value and goes on without noticing the *

如果有人无意中试图在更广泛的范围内重新定义myDiv(虽然不是这么好的想法......),后一种方法的优点是保持代码安全,用一些不同的值覆盖它并继续而不注意冲突

That’s the main reason why this is a bad idea, and it’s quite enough. Global variables aren’t safe to rely on. They can be overwritten at any time, by any script that ends up running on the page.

这就是为什么这是一个坏主意的主要原因,而且这已经足够了。全局变量不能安全依赖。它们可以随时被任何最终在页面上运行的脚本覆盖。

In addition to that, just typing in myDiv isn’t a “short form” of document.getElementById(). It’s a reference to a global variable.document.getElementById() will happily return null if the element doesn’t exist, whilst attempting to access a non-existent global variable will throw a reference error, so you’d need to wrap your references to the global in a try/catch block to be safe.

除此之外,只输入myDiv不是document.getElementById()的“简短形式”。它是对全局变量的引用。如果元素不存在,则会愉快地返回null,而尝试访问不存在的全局变量将引发引用错误,因此您需要包装引用到try / catch块中的全局是安全的。

This is one reason why jQuery is so popular: if you do $("#myDiv").remove(), and there is no element with an id of myDiv, no error will be thrown — the code will just silently do nothing, which is often exactly what you want when doing DOM manipulation.

这就是为什么jQuery如此受欢迎的一个原因:如果你做$(“#myDiv”)。remove(),并且没有id为myDiv的元素,就不会抛出任何错误 - 代码只会默默地做什么,这通常是您在进行DOM操作时所需要的。

#3


11  

There are a few reasons:

有几个原因:

You don't want your code and your markup that coupled.

您不希望您的代码和标记耦合在一起。

By using a specific call to access a div, you don't have to worry about the global space being corrupted. Add a library that declares myDiv in global space and you're in a world of pain that will be hard to fix.

通过使用特定的调用来访问div,您不必担心全局空间被破坏。添加一个在全局空间中声明myDiv的库,您将陷入一个难以修复的痛苦世界。

You can access elements, by ID, that aren't part of the DOM

您可以按ID访问不属于DOM的元素

They can be in a fragment, a frame, or an element that has been detached and not re-attached to the DOM yet.

它们可以位于片段,框架或已分离但尚未重新附加到DOM的元素中。

EDIT: Example of accessing a non-attached elements by ID

编辑:按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);