2011-09-30 40 views
4

考虑这个HTML源代码:在IE和Opera中添加名称属性导致ID值成为文档对象的属性?

<form id="foo1" name="x"> Form 1 </form> 
<form id="foo2"> Form 2 </form> 

正如你所看到的,我们定义了两个表单元素。

在Chrome,Safari和Firefox中,document.foo1document.foo2均返回undefined

但是,在IE和Opera中,document.foo1返回对相应FORM元素的引用,而document.foo2返回undefined

现场演示:http://jsfiddle.net/zrmEm/2/

所以,第一种形式确实有它的ID命名的属性的文档对象,第二个表格没有。这种差异是将name属性添加到第一种形式的结果。

现在,那里的逻辑在哪里?这是一个已知的行为吗?

+0

你应该简单地忽略这些浏览器做的和不做的全局变量,因为你不应该使用它们。他们不是标准的。使用'document.getElementById()'获得一个带有id的对象的DOM引用。它不同于一个浏览器的原因是它不是由标准定义的。 – jfriend00

+1

只是不要让Google知道它,否则他们会将其添加到Chrome的下一个版本中。我的意思是他们已经得到了'document.all'和'window.event'的好处。似乎他们暗中想成为IE! – user113716

+1

@Ӫ_._Ӫ为时已晚。 Chrome浏览器(以及其他浏览器)确实添加了“遍布全球”的窗口和文档属性。例如,对于上面的HTML代码,Chrome会创建3个全局属性:'window.foo1','window.foo2'和'window.x',以及一个文档属性:'document.x'(所有这些都是对表格)。这种全球命名空间污染至少可以说是令人不安的,但除了Firefox(!!)之外的所有浏览器都这样做。 **演示:** http://jsfiddle.net/c4tTw/ –

回答

1

在所有的浏览器,表单的名称属性的值被添加作为文档对象的属性,并且还作为document.formscollection的性质。

如果您使用的是ids,则这些值仅作为表格集合的属性添加。

IE总是对名称和id属性感到困惑。在IE(测试版本8)中,如果还有该表单的名称(可能与id相同或不同),则会添加文档的属性

所以,如果你总是使用document.forms ['name-or-id']那么生活是甜蜜的。只要您没有名称与其他带有ID的表单相同的表格,则所有投注都将关闭。

+0

呃...你的回答是准确的,据我所知,你的表述比我的更好。所以我刚刚删除了我的:P –

+0

只是为了补充一点,需要注意的是'id's和'name's驻留在相同的命名空间中。如果你有一个独特的元素*应该*具有'name'属性,'id'和'name'匹配是明智的。 – 2011-09-30 15:43:30

1

这基本上是微软在浏览器战争黑暗时期推出的一种怪癖。 (大约IE4)

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

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

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

然而,这个特殊功能没有。它仍然是非标准的。

即使在较新版本的浏览器中,微软仍旧保留了大部分旧的非标准功能,以努力保持旧代码的向后兼容性(许多企业内部网由微软培训的“专家”编写,并使用这些功能,所以他们需要保持它们,否则没有人会永远升级过去的IE6)。

在那些日子里,Opera是浏览器世界的年轻伪装者。它经常更新,具有创新功能,并且比竞争对手跑得快得多。他们当时正在为浏览器世界做最近Chrome的做法。但是由于标准战争的不断升级,Opera能够竞争的唯一方式就是兼容,他们竭尽全力在IE中对所有功能进行反向工程(甚至在某些情况下还会出现bug),以便站点为IE编写的代码也可以在Opera中使用。

这显然是这些功能之一,这就是为什么IE和Opera今天都有共同的怪癖。

今天市场上的其他浏览器没有相同的历史。 Firefox最终来源于Netscape Navigator,尽管它可能有自己的怪癖可以追溯到那些日子,但它不会共享IE的。而webkit浏览器有更近期的出处(它来源于KDE Project的KHTML引擎),所以它再也没有尝试模拟IE的怪癖。