最佳实践:通过HTML标识或名称属性访问表单元素?

正如任何经验丰富的JavaScript开发人员所知道的,有很多(太多)方法可以做同样的事情。 例如,假设你有一个文本字段如下:

<form name="myForm"> <input type="text" name="foo" id="foo" /> 

有很多方法可以在JavaScript中访问:

 [1] document.forms[0].elements[0]; [2] document.myForm.foo; [3] document.getElementById('foo'); [4] document.getElementById('myForm').foo; ... and so on ... 

方法[1]和[3]在Mozilla Gecko文档中有详细logging,但都不是理想的。 [1]只是太泛泛而无用,[3]需要一个id和一个名字(假设你将数据发布到服务器端语言)。 理想情况下,最好只有id属性或name属性(两者都有些多余,特别是如果id不是任何css所必需的,并增加了拼写错误的可能性等)。

[2]似乎是最直观的,它似乎被广泛使用,但我没有看到它在Gecko文档中引用,我担心向前兼容性和跨浏览器兼容性(当然,我想成为作为尽可能符合标准)。

那么这里最好的做法是什么? 任何人都可以指出可以解决这个问题的DOM文档或W3C规范的东西?

注意我特别感兴趣的是非库解决scheme(jQuery / Prototype)。

只给你的表单一个id ,而你的input只有一个名字

 <form id="myform"> <input type="text" name="foo"> 

那么访问你的input元素的最符合标准和最不成问题的方式是通过:

 document.getElementById("myform").elements["foo"] 

使用.elements["foo"]而不是.foo是可取的,因为后者可能会返回名为“foo”的表单而不是HTML元素的属性!

[1] document.forms [0] .elements [0];

当我看到这种元素访问的方法时,想到“ No-omg-never! ”。 这个问题是假定DOM是一个正常的数据结构(例如:一个数组),其中元素顺序是静态的,一致的或可靠的。 我们知道99.9999%的时间,这并非如此。 在表单中重新sorting或input元素,在表单有问题之前向页面添加另一个form ,或移动表单时,都是代码中断的情况。 小故事:这是非常脆弱的。 只要你添加或移动的东西,它会打破。

[2] document.myForm.foo;

我和Sergey ILinsky就这个问题进行了讨论:

  • 通过引用它们的id属性访问任意元素: document.getElementById("myform");
  • 按名称访问命名表单元素,相对于其父窗体元素: document.getElementById("myform").foo;

我用这个方法的主要问题是name属性在应用于表单时是无用的。 该名称不作为POST / GET的一部分传递给服务器,不适用于散列样式书签。

document.getElementById('foo');

在我看来,这是最好的方法。 直接访问是最简洁明了的方法。

[4] document.getElementById('myForm')。foo;

在我看来,这是可以接受的,但是比必要的更冗长。 方法#3是优选的。


我只是碰巧看了道格拉斯·克罗克福德(Douglas Crockford)的一段video ,他对这个主题感兴趣。 兴趣点在-12:00。 总结:

  • 文档集合(document.anchor,document.form等)已经过时和不相关(方法1)。
  • name属性用于命名事物,而不是访问它们。 这是命名的东西,如窗口,input字段和锚标签。
  • “ID是你应该用来唯一标识一个元素,以便你可以访问它的东西,它们(名字和ID)以前是可以互换的,但是现在已经不存在了。

所以你有它。 从语义上讲,这是最有意义的。

要访问放置在表单中的指定元素,最好使用form对象本身。

要访问有时可能在表单中find的DOM树中的任意元素,请使用getElementById和元素的id

我更喜欢第五种方法。 那是
[5]使用特殊的JavaScript标识符将表单或字段对象传递给事件处理程序的函数。

具体来说,对于表单:

 <form id="form1" name="form1" onsubmit="return validateForm(this)"> 

 // The form validation function takes the form object as the input parameter function validateForm(thisForm) { if (thisform.fullname.value !=... 

使用这种技术,该function从来不需要知道
– 页面中定义表单的顺序,
– 表单ID,也不是
– 表单名称

同样,对于领域:

 <input type="text" name="maxWeight"> ... <input type="text" name="item1Weight" onchange="return checkWeight(this)"> <input type="text" name="item2Weight" onchange="return checkWeight(this)"> 

 function checkWeight(theField) { if (theField.value > theField.form.maxWeight.value) { alert ("The weight value " + theField.value + " is larger than the limit"); return false; } return true; } 

在这种情况下,函数不必知道特定权重字段的名称或ID,尽pipe它确实需要知道权重限制字段的名称。

这不是真的回答你的问题,而只是在这个部分:

[3]需要一个id和一个名字…两者都有点多余

您很可能需要在每个表单字段上都有一个id属性,以便您可以将它的<label>元素与它关联,如下所示:

 <label for="foo">Foo:</label> <input type="text" name="foo" id="foo" /> 

这对于可访问性是必需的(即,如果你不关联表单标签和控件,为什么你这么讨厌盲人?)。

这有点多余,但是当你有checkbox/单选button,其中几个可以共享一个name 。 最终, idname是为了不同的目的,即使两者经常被设置为相同的值。

老式我一直使用'document.myform.myvar'语法,但我最近发现它在Chrome中失败(在Firefox和IE中确定)。 这是一个Ajax页面(即加载到div的innerHTML属性)。 也许Chrome并没有将表单识别为主文档的一个元素。 我用getElementById(而不是引用表单),而且它工作正常。

这是有点老,但我想添加一个我认为是相关的东西。
(我打算评论一个或两个以上的线程,但似乎我需要声望50,而我只有21个时候我写这个:))
只是想说,有时候通过名称而不是id来访问表单的元素会好得多。 我不是在谈论forms本身。 表单,好的,你可以给它一个ID,然后通过它来访问它。 但是如果你在表单中有一个单选button,那么把它作为一个单独的对象(获取和设置它的值)就容易得多,而且只能按照我的名字来完成。

例:

 <form id="mainForm" name="mainForm"> <input type="radio" name="R1" value="V1">choice 1<br/> <input type="radio" name="R1" value="V2">choice 2<br/> <input type="radio" name="R1" value="V3">choice 3 </form> 

您可以通过使用来获取/设置单选buttonR1的选中值
document.mainForm.R1.value
要么
的document.getElementById( “MainForm的”)。R1.value
所以,如果你想有一个单一的风格,你可能总想使用这个方法,而不pipe表单元素的types。 我,我很舒服地访问单选button的名称和文本框的ID。

表格2可以,表格3也是推荐的。
name和id之间的冗余是由于需要保持兼容性而引起的,在html5上,一些元素(如img,form,iframe等)将失去它们的“name”属性,build议从现在开始只使用它们的id来引用它们上 :)

为了补充其他答案,document.myForm.foo是所谓的DOM级别0,这是Netscape实现的方式,因此即使它被大多数浏览器支持,也不是真正的开放标准。

看看这个页面: https : //developer.mozilla.org/En/DOM/Document.getElementsByName

 document.getElementsByName('foo')[0]; // returns you element. 

它必须是“元素”,并且必须返回一个数组,因为多个元素可以具有相同的名称。

我的答案在确切的问题上会有所不同。 如果我想访问特定的元素,那么我将使用document.getElementById()。 一个例子是计算一个人的全名,因为它是build立在多个领域,但它是一个可重复的公式。

如果我想访问元素作为function结构(表单)的一部分,那么我会使用:

 var frm = document.getElementById('frm_name'); for(var i = 0; i < frm.elements.length;i++){ ..frm.elements[i].. 

这也是从业务的angular度来看也是如此。 循环内的变化与应用程序中的function变化一起发生,因此是有意义的。 我主要将它用于用户友好的validation,并防止networking调用检查错误的数据。 我重复validation服务器端(并添加一些更多),但如果我可以帮助用户客户端,那么是有利于所有。

对于数据聚合(例如基于表单中的数据构build饼图),我使用configuration文档和自定义的Javascript对象。 然后是与其上下文相关的字段的确切含义,并使用document.getElementById()。