具有ID的DOM树元素是否会成为全局变量?

2020/09/30 02:01 · javascript ·  · 0评论

在研究一个简单的HTMLElement包装器的想法时,我偶然发现了Internet Explorer和Chrome的以下内容

对于DOM树中具有ID的给定HTMLElement,可以使用其ID作为变量名称来检索div。所以对于像

<div id="example">some text</div>

Internet Explorer 8和Chrome中,您可以执行以下操作:

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

要么

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

那么,这是否意味着DOM树中的每个元素都将转换为全局名称空间中的变量?这是否还意味着可以使用它代替getElementById这些浏览器中方法?

应该发生的是添加了“命名元素”作为document对象的明显属性这是一个非常糟糕的主意,因为它允许元素名称与的实际属性冲突document

IE也通过添加命名元素作为window对象的属性来使情况变得更糟这是双重不利的,因为现在您必须避免在您可能想要使用documentwindow对象(或项目中的任何其他库代码)的任何成员之后命名元素

这也意味着这些元素作为全局变量可见。幸运的是,在这种情况下,代码中的任何实际全局变量varfunction声明都将它们隐藏起来,因此您不必担心在此处命名,但是如果您尝试对名称冲突的全局变量进行赋值而忘记声明它var,您将在IE中遇到错误,因为它试图将值分配给元素本身。

通常,忽略var和依赖于在window全局变量或作为全局变量可见的命名元素被认为是不好的做法坚持document.getElementById,这是获得更广泛支持和较少含糊的内容。如果您不喜欢键入,则可以使用短名称编写平凡的包装函数。无论哪种方式,使用id到元素的查找缓存都是没有意义的,因为浏览器通常会优化getElementById调用以使用快速查找。当元素更改id或从文档中添加/删除元素时,您得到的只是问题

歌剧复制IE,然后WebKit的加入进来,现在都将命名元素上的以前不标准,实践document特性,并把他们的先前IE-只有实践window 标准化的HTML5,其方法是将文件和规范每浏览器作者对我们施加了可怕的习俗,使他们永远成为网络的一部分。因此,Firefox 4也将支持此功能。

什么是“命名元素”?带有id,和带有name用于“标识”目的的任何东西:即表单,图像,锚点和其他一些name属性,但没有其他与属性无关的实例,例如表单输入字段中的控件名称,<param>或中的元数据类型<meta>name应该避免使用“标识”来代替id

如前面的答案中提到的,此行为称为window对象上的命名访问该值name的某些元素属性和值id的所有元素的属性都可用作为全球性质window的对象。这些被称为命名元素。由于window是浏览器中的全局对象,因此每个命名元素都可以作为全局变量访问。

它最初是由Internet Explorer添加的,最终由所有其他浏览器实现,只是为了与依赖此行为的网站兼容。有趣的是,Gecko(Firefox的渲染引擎)选择仅以怪癖模式实现此功能,而其他渲染引擎则将其保留为标准模式。

但是,从Firefox 14开始,Firefox现在也支持window在标准模式下对象的命名访问他们为什么要改变这一点?事实证明,仍有很多站点在标准模式下依赖此功能。微软甚至发布了一个营销演示,阻止了该演示在Firefox中运行。

Webkit最近考虑了相反的做法window对象上的命名访问权限授予怪癖模式。他们以与壁虎相同的理由决定反对。

因此,……似乎很疯狂,因为从技术上来说,现在在标准模式下的所有主流浏览器的最新版本中都可以安全使用此行为但是,尽管命名访问似乎有点方便,但不应使用它

为什么?关于全局变量为何坏的原因,本文可以总结很多原因简而言之,拥有大量额外的全局变量会导致更多错误。假设您不小心输入了a的名称,var而偶然输入id了DOM节点SURPRISE的an

此外,尽管已标准化,但浏览器的命名访问实现仍存在许多差异。

  • IE错误地使name属性的值可用于表单元素(输入,选择等)。
  • Gecko和Webkit错误地使<a>标签无法通过其name属性进行访问
  • Gecko错误地处理具有相同名称的多个命名元素(它返回对单个节点的引用,而不是引用数组)。

而且我敢肯定,如果您尝试在边缘情况下使用命名访问,还会有更多。

如其他答案中所述,document.getElementById用于通过DOM节点获取对DOM节点的引用id如果需要通过其name属性获取对节点的引用,请使用document.querySelectorAll

请,请不要通过在您的站点中使用命名访问来传播此问题。因此,许多Web开发人员都在浪费时间来尝试这种神奇的行为。我们确实需要采取行动,并使渲染引擎在标准模式下关闭命名访问。从短期来看,它将破坏一些做坏事的网站,但从长远来看,它将帮助推动网络向前发展。

如果您有兴趣,请在我的博客-https: //www.tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/上更详细地讨论

getElementById()在这些情况下,您应该坚持使用,例如:

document.getElementById('example').innerHTML

IE喜欢在全局命名空间中将元素与name ID属性混合使用,因此最好明确说明您要获取的内容。

是的,他们有。

已在Chrome 55,Firefox 50,IE 11,IE Edge 14和Safari 10中

通过以下示例进行了测试:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <div id="im_not_particularly_happy_with_that">
    Hello World!
  </div>
  <script>
    im_not_particularly_happy_with_that.innerText = 'Hello Internet!';
  </script>
  <!-- Looking at you W3 HTML5 spec group ಠ_ಠ -->
</body>
</html>

http://jsbin.com/mahobinopa/edit?html,输出

这个问题听起来应该是:“具有提供的ID的HTML标签是否会成为可全局访问的DOM元素?”

答案是肯定的!

这就是它的工作方式,这就是W3C最初引入ID的原因

但是,Netscape Mozilla拒绝遵循(入侵他们)W3C,并顽固地使用不推荐使用的Name属性来造成破坏,因此破坏了W3C引入唯一ID所带来的脚本功能和编码便利性。

在Netscape Navigator 4.7惨败之后,他们的开发人员全都去渗透了W3C,而他们的同事却以错误的做法和错误的示例取代了Web。强制使用和重用已经过时的Name属性[!并不是唯一的]与ID属性相提并论,以便利用ID句柄访问特定DOM元素的脚本会被破坏!

并打破他们做了,因为他们也撰写和发表大量的编码的经验教训和例子[他们的浏览器将不会反正承认]例如 document.all.ElementID.property,而不是ElementID.property至少使其效率低下,更多的开销给浏览器的情况下,它没有简单地打破它HTML域,方法是使用相同的标记(现在[1996-97],已弃用),名称和标准ID属性为其提供相同的标记值。

他们很容易地说服了当时的绝大多数无知的代码编写爱好者,使他们知道Name和ID实际上是相同的,除了ID属性更短,因此比古老的Name属性更节省字节和更方便编码。这当然是骗人的。或者-在取代HTML的已发表文章中,说服您需要为标签提供名称和ID,以便脚本引擎可以访问它们。

马赛克杀手[代号“ Mozilla”]非常生气,他们以为“如果我们失败了,互联网也应该如此”。

另一方面,崛起的Microsoft太天真了,他们以为应该保留不推荐使用的标记并标记为删除Name属性,并将其视为唯一的ID来对待,以便他们不会破坏的脚本功能Netscape学员编码的旧页面。他们是致命的错误...

而且,返回ID冲突元素的数组集合也不是解决此人为问题的方法。实际上,它打败了整个目标。

这是W3C变得丑陋并给了我们白痴和诸如此类document.getElementById的伴随洛可可式令人讨厌的语法的唯一原因...(...)

本文地址:http://javascript.askforanswer.com/juyouiddedomshuyuansushifouhuichengweiquanjubianliang.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!