代码之家  ›  专栏  ›  技术社区  ›  m.y.m

html:id与标记[重复]同名

  •  0
  • m.y.m  · 技术社区  · 7 年前

    在开发一个简单的HTMLElement包装器的想法时,我偶然发现了InternetExplorer和 Chrome :

    对于DOM树中ID为的给定htmlelement,可以使用其ID作为变量名来检索DIV。所以对于像迪夫这样的人来说

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

    在里面 Internet Explorer 8 还有铬,你可以做到:

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

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

    那么,这是不是意味着 DOM树中的每个元素 是否转换为全局命名空间中的变量?这也意味着我们可以用它来替代 getElementById 这些浏览器中的方法?

    0 回复  |  直到 7 年前
        1
  •  368
  •   T.J. Crowder    9 年前

    应该发生的是,将命名元素作为 document 对象。这是一个非常糟糕的主意,因为它允许元素名与 文件 .

    IE还添加了命名元素作为 window 对象。这是一个双重的错误,因为现在您必须避免将元素命名为 文件 或者 窗口 对象(或项目中的任何其他库代码)可能要使用。

    它还意味着这些元素作为全局变量可见。幸运的是,在这种情况下,任何真正的全球 var function 代码中的声明隐藏了它们,因此您不必在这里为命名担心太多,但是如果您试图对一个具有冲突名称的全局变量进行赋值,而忘记了声明它。 var ,您将在IE中得到一个错误,因为它试图将值赋给元素本身。

    省略通常被认为是不好的做法 var 以及依赖于可见的命名元素 窗口 或者作为全局变量。坚持 document.getElementById 更广泛的支持,更不含糊。如果不喜欢键入内容,可以用较短的名称编写一个简单的包装函数。不管怎样,使用id-to-element查找缓存都没有意义,因为浏览器通常会优化 getElementById 调用以使用快速查找;您所得到的只是元素更改时的问题。 id 或从文档中添加/删除。

    Opera复制了IE,然后WebKit加入了,现在这两种方法都是以前不标准的将命名元素加入 文件 属性,以及以前唯一的 窗口 being standardised HTML5的方法是记录和标准化浏览器作者给我们带来的每一个可怕的实践,使它们永远成为网络的一部分。所以火狐4也支持这一点。

    什么是命名元素?任何带有 身份证件 以及任何带有 name 用于识别目的:即窗体、图像、锚定和其他一些,但不是其他与 名称 属性,如窗体输入字段中的控件名称,参数名称 <param> 或元数据类型 <meta> . 识别 名称 S是应该避免的有利于 身份证件 .

        2
  •  46
  •   TJ VanToll    8 年前

    如前所述,这种行为称为 named access on the window object . 的值 name 一些元素的属性和 id 所有元素的属性都可用作全局的属性 window 对象。这些被称为命名元素。自从 窗口 是浏览器中的全局对象,每个命名元素都可以作为全局变量访问。

    它最初由Internet Explorer添加,最终由所有其他浏览器实现,只是为了与依赖于此行为的站点兼容。有趣的是,Gecko(火狐的渲染引擎)选择在 quirks mode 只有,而其他渲染引擎将其保留在标准模式下。

    但是,从火狐14开始, Firefox now supports named access 窗口 对象也处于标准模式。他们为什么要改变这个?事实证明,在标准模式下仍然有很多网站依赖于此功能。微软偶数 released a marketing demo 确实如此,阻止了演示在Firefox中工作。

    WebKit最近 considered the opposite ,将上的命名访问 窗口 对象仅限怪癖模式。他们以和壁虎一样的理由反对它。

    所以这个行为现在看起来很疯狂 在标准模式下,在所有主要浏览器的最新版本中使用在技术上是安全的 . 但是,尽管命名访问看起来有些方便, 不应该使用 .

    为什么?这篇文章可以总结出很多关于为什么 global variables are bad . 简单地说,拥有一堆额外的全局变量会导致更多的错误。假设您不小心输入了 var 恰好是安型的 身份证件 一个dom节点,惊喜!

    此外,尽管标准化了,但是在浏览器的命名访问实现中仍然存在相当多的差异。

    • ie错误地使 名称 表单元素(输入、选择等)可访问的属性。
    • Gecko和Webkit不正确 <a> 通过他们的 名称 属性。
    • gecko错误地处理多个同名的命名元素(它返回对单个节点的引用,而不是引用数组)。

    我相信如果你尝试在边缘案例上使用命名访问,会有更多的内容。

    如其他答案所述,使用 document.getElementById 通过它的 身份证件 . 如果需要通过 名称 属性使用 document.querySelectorAll .

    请不要在站点中使用命名访问来传播此问题。很多Web开发人员都浪费时间来跟踪这个问题 神奇的 行为。我们真的需要采取行动,让渲染引擎在标准模式下关闭命名访问。从短期来看,它会破坏一些做坏事的网站,但从长远来看,它将有助于推动网络向前发展。

    如果你感兴趣的话,我会在我的博客上详细讨论这个问题。- https://www.tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/ .

        3
  •  20
  •   Nick Craver    16 年前

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

    document.getElementById('example').innerHTML
    

    我喜欢把元素和 name ID 全局名称空间中的属性,因此最好明确说明您要获取的内容。

        4
  •  3
  •   qff    8 年前

    是的,他们有。

    在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,output

        5
  •  2
  •   Bekim Bacaj    7 年前

    问题应该是这样的:“带有所提供ID的HTML标记是否成为全局可访问的DOM元素?”

    答案是肯定的!

    这就是它的工作方式,这就是为什么W3C首先引入了ID。 解析脚本环境中HTML标记的ID将成为其相应的DOM元素句柄。

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

    在Netscape Navigator 4.7失败之后,他们的开发人员都去渗透W3C,而他们的同事则用错误的实践和错误的示例取代了Web。强制使用和重用已弃用的名称属性[!这并不意味着是唯一的]与ID属性一样,这样使用ID句柄访问特定的DOM元素的脚本就会被破坏!

    并打破他们的做法,因为他们也会编写和发布大量的编码课程和示例[他们的浏览器无论如何都无法识别],例如 document.all.ElementID.property 而不是 ElementID.property 至少要使其效率低下,并给浏览器更多的开销,以防它没有简单地在HTML域中使用相同的令牌(现在[1996-97],已弃用)名称和提供相同令牌值的标准ID属性来破坏它。

    他们很容易就说服了那些无知的代码编写爱好者,他们认为名称和ID实际上是一样的,只是ID属性比古老的名称属性更短,因此节省了字节,而且对编码人员来说更方便。这当然是个谎言。或者-在他们取代发布的HTML文章中,令人信服的文章认为您需要为标签提供名称和ID,以便脚本引擎可以访问它们。

    马赛克杀手[代号为“Mozilla”]非常愤怒,他们认为“如果我们倒下了,互联网也应该倒下”。

    另一方面,正在崛起的微软太幼稚了,他们认为应该保留已弃用并标记为删除名称的属性,并将其视为唯一标识符的ID,这样他们就不会破坏由Netscape受训人员编码的旧页面的脚本功能。他们犯了致命的错误…

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

    这就是W3C变丑的唯一原因,给了我们一些愚蠢的想法,比如 document.getElementById 伴随着洛可可该死的烦人的句法… (……)