Javascript 添加name属性会导致ID值成为IE和Opera中文档对象的属性?

Javascript 添加name属性会导致ID值成为IE和Opera中文档对象的属性?,javascript,html,internet-explorer,dom,opera,Javascript,Html,Internet Explorer,Dom,Opera,考虑以下HTML源代码: <form id="foo1" name="x"> Form 1 </form> <form id="foo2"> Form 2 </form> 表格1 表格二 如您所见,我们定义了两个表单元素 在Chrome、Safari和Firefox中,都是document.foo1和document.foo2returnundefined 但是,在IE和Opera中,document.foo1返回对相应表单元素的引用,而doc

考虑以下HTML源代码:

<form id="foo1" name="x"> Form 1 </form>
<form id="foo2"> Form 2 </form>
表格1
表格二
如您所见,我们定义了两个表单元素

在Chrome、Safari和Firefox中,都是
document.foo1
document.foo2
return
undefined

但是,在IE和Opera中,
document.foo1
返回对相应表单元素的引用,而
document.foo2
返回
未定义的

现场演示:

因此,第一个表单在document对象中有其ID-named属性,而第二个表单没有。这种差异是将
name
属性添加到第一个表单的结果


现在,这其中的逻辑在哪里?这是一种已知的行为吗?

在所有浏览器中,表单名称属性的值都作为document对象的属性以及document.forms的属性添加

如果使用的是ID,则这些值仅作为表单集合的属性添加

IE总是混淆名称和id属性。在IE(已测试版本8)中,id仅添加到文档的属性中,如果该表单也有名称(可能与id相同或不同)


所以,如果你总是使用document.forms['name-or-id'],那么生活是美好的。只要您的表单名称与其他具有ID的表单名称相同,那么所有的赌注都是无效的。

这基本上是微软在浏览器大战的黑暗时期引入的一个怪癖。(约IE4)

最终的结果是,在IE中,表单将作为变量添加到文档范围中,以便您可以将它们作为
document.form1
引用

这是非标准的,但这在当时似乎并不重要(至少对浏览器供应商来说不是)

当时添加到一个或另一个浏览器中的许多非标准功能最终被其他浏览器实现,成为事实上的标准,并最终成为官方标准

然而,这一特殊功能并未实现。它仍然是非标准的

为了保持对旧代码的向后兼容性,微软保留了大部分旧的非标准功能,即使在新版浏览器中也是如此(许多公司内部网都是由微软培训的“专家”编写的,并使用这些功能,所以他们需要保留这些功能,否则没有人会升级到IE6之上)

在那些日子里,Opera是浏览器世界中年轻的伪装者。它经常更新,具有创新功能,运行速度比竞争对手快得多。那时,他们正在为浏览器世界做Chrome最近做的事情

然而,由于标准战不断升级,Opera唯一能与之竞争的方式就是兼容,他们竭尽全力对IE中的所有功能(甚至在某些情况下是bug)进行反向工程,以便为IE编写的站点也能在Opera中工作

这显然是其中的一个特点,这就是为什么IE和Opera今天都有相同的怪癖


今天市场上的其他浏览器没有相同的历史。Firefox最终是从Netscape Navigator衍生而来的,所以尽管它可能有自己的怪癖,但它不会与IE分享。而且webkit浏览器的出处更近(它源自KDE项目的KHTML引擎),因此它也从未有过试图模仿IE怪癖的历史。

你应该忽略这些浏览器的全局变量,因为你不应该使用它们。它们不是标准的。使用
document.getElementById()
获取对具有id的对象的DOM引用。不同浏览器之间的DOM引用不同的原因在于它不是由标准定义的。只是不要让Google知道,否则他们会将其添加到下一版本的Chrome中。我的意思是,看在上帝的份上,他们已经有了
文档.all
窗口.event
。似乎他们暗地里想成为IE@太晚了。Chrome(和其他浏览器)确实“到处”添加窗口和文档属性。例如,对于上面的HTML代码,Chrome将创建3个全局属性:
window.foo1
window.foo2
window.x
,以及一个文档属性:
document.x
(所有这些都是对表单的引用)。这种全局名称空间污染至少有点令人不安,但除了Firefox(!!)之外的所有浏览器都会这样做。演示:不仅如此-opera和IE(甚至10)将带有id的所有内容添加到window对象中。alert(elementid)返回对该对象的引用,就像是一个全局变量。您非常小心地避免污染全局名称空间……我想到了WHAT WG IRC频道的主题:“请将您的逻辑感留在门上,谢谢。”。不,这是没有逻辑的。Opera决定这样做(现在),因为我们找到了一个依赖它的页面。如果我们认为可以在网络上逍遥法外,我们可能会决定在不久的将来停止这样做。所以请帮我们放下它-不要写任何依赖于这个怪癖的脚本:)。呃。。。据我所知,你的回答是准确的,你的表达比我的好。因此,我刚刚删除了我的:p为了补充这一点,需要注意的是,
id
s和
name
s位于同一名称空间中。如果您有一个应具有
名称
属性的唯一元素,则明智的做法是将
id
名称
匹配。