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

GOT*_*O 0 52 javascript dom getelementbyid

我开始使用的所有浏览器都允许id="myDiv"通过简单地编写来访问元素:

myDiv
Run Code Online (Sandbox Code Playgroud)

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

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

document.getElementById("myDiv")
Run Code Online (Sandbox Code Playgroud)

或者可能

document.querySelector("#myDiv")
Run Code Online (Sandbox Code Playgroud)

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

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

joe*_*ews 43

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

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

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

编辑:原来,这种行为符合标准的-在HTML5中,window应该支持"命名元素"访问属性:

出于上述算法的目的,具有名称名称的命名对象是以下任一种:

  • 活动文档的名字是孩子浏览上下文的名字,
  • a,applet,area,embed,form,frameset,img或具有名称内容属性,其值为name的对象元素,或者
  • 具有id内容属性,其值为name的 HTML元素.

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

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

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

  • 为什么规范会指定一些内容然后建议不要使用它?!好像网络需要更多不良做法.#捂脸# (14认同)
  • 我猜想这是一种正式支持已经落入普通(ish)用途的遗留模式的方法. (6认同)
  • AFAIK`name!= id`(必要),我从未发现任何文档明确声明你不能拥有1个名为="foo"的元素而另一个元素的id ="foo"(可能已经错过了它),所以还有1个级别的歧义.我没有看到名称和身份证上的重点 - 直到分离它们在GTK3的API(特别是gtkbuilder xml用户界面)中打破了一堆东西. (2认同)
  • @Izkata我知道,你宁愿从别人的错误中吸取教训.gtkbuilder和gtk3样式的大部分是在html和css之后建模的,然后当他们认为javascript将是构建gtk3应用程序的第一类语言时,他们修改了名称〜= id的旧行为并且破坏了很多东西.. .作为全局变量引用name和id的能力是非常相似的,我怀疑在未来的版本中,名称完全消失或名称获得全局处理(非js浏览器的许多遗留形式依赖于它)和id需要获得(只是猜测). (2认同)
  • 鉴于编辑和更新,我没有看到不使用此功能的原因. (2认同)

Pau*_*ite 20

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

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

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

除此之外,只需输入myDiv就不是"简短形式" document.getElementById().它是对全局变量的引用.如果元素不存在,document.getElementById()将很乐意返回null,而尝试访问不存在的全局变量将引发引用错误,因此您需要将对try/catch块中的全局引用包装起来是安全的.

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

  • 具有讽刺意味的是,无声的失败也是人们不喜欢jQuery的一个原因. (7认同)
  • 如果元素不存在,`document.getElementById()`返回`null`,而不是'undefined`. (2认同)

Jer*_*her 12

有几个原因:

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

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

您可以按ID访问不属于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);
Run Code Online (Sandbox Code Playgroud)