浏览器是否支持对由 id 命名的 html 元素的全局引用?

Do browsers support global references to html elements named by id?

我不小心在 JavaScript 中输入了以下代码,它起作用了:

my_element.addEventListener("click", function() {
  alert("Hello world");  
})
#my_element {
  background: lightblue;
  width: 100px;
  height: 100px;
  position: absolute;
  top: 50px;
  left: 50px;
}
<div id="my_element">hello there</div>

我没有使用以下方法获取元素:

var element = document.getElementById("my_element");

我只是像这样引用了元素并且它起作用了!?!

my_element.addEventListener("click", function() {
  alert("Hello world");  
})

这适用于 Firefox 和 Chrome。我没有在其他浏览器中测试过。这是众所周知的吗?这在浏览器中是否完全受支持?

我总是返回对 HTML 元素的引用。令我震惊的是,我可以简单地键入元素的 ID,就好像它是一个全局对象一样!

是的,它得到了普遍支持,甚至现在 in the HTML5 specification。为每个带有 id 的元素(以及许多其他带有 name 的元素)创建自动全局变量。

我从不依赖它,全局命名空间中的其他东西太多了。但是,是的,它是定义的行为。


在下面的评论中,您询问了发生冲突时会发生什么。 中有更多内容,但有一个命令。自动 DOM 全局变量以几种不同的方式被声明的全局变量隐藏。这是一个例子:

// `example1` is a DOM automatic global
console.log(typeof example1);                                        // object
console.log("example1" in this);                                     // true
console.log(Object.prototype.hasOwnProperty.call(this, "example1")); // false

// We have both a DOM element with `example2` as its ID and also a
// `var`-declared global; the latter takes precedence
var example2;
console.log(typeof example2);                                        // undefined
console.log("example2" in this);                                     // true
console.log(Object.prototype.hasOwnProperty.call(this, "example2")); // true

// We have a DOM element with `example3` as its ID, a global object property
// with that name, and also a `let`-declared global variable; the latter wins
this.example3 = 42;
let example3;
console.log(typeof example3);                                        // undefined
console.log("example3" in this);                                     // true
console.log(Object.prototype.hasOwnProperty.call(this, "example3")); // true
.as-console-wrapper {
    max-height: 100% !important;
}
<div id="example1"></div>
<div id="example2"></div>
<div id="example3"></div>


在您提出的进一步评论中:

What of the case of conflicts with existing global members? For example, if I name my element "window" or "document"? Will my element take precedents over the existing global object member?

不,windowdocumentothers是Window对象的自己的属性,但是自动DOM 全局变量在其原型上(在兼容的浏览器上;不是 IE11 或 IIRC Legacy Edge)。所以它自己的属性赢了。要获得自动 DOM 全局变量,您必须转到 window 的原型:

// `window` here is still the global object
console.log(window === this);                              // true
var someVariableName;
console.log("someVariableName" in window);                 // true

// The automatic DOM global "window" is on its prototype:
console.log(Object.getPrototypeOf(window).window.tagName); // "DIV"
<div id="window"></div>

当然,none 这是您要依赖的行为。如果要通过 id 访问 DOM 元素,请使用 getElementById(或 querySelector 或类似的)。