最佳实践:按HTML ID或名称属性访问表单元素?

时间:2010-03-12 20:07:15

标签: javascript html forms dom

任何经验丰富的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文档中有详细记载,但两者都不理想。 [1]过于笼统而无用,[3]同时需要id和名称(假设您将数据发布到服务器端语言)。理想情况下,最好只有一个id属性或一个name属性(两者都有点多余,特别是如果id不是任何css所必需的,并且增加了拼写错误的可能性等等)。

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

那么这里的最佳做法是什么?任何人都可以在DOM文档或W3C规范中指出可以解决此问题的内容吗?

注意我对非库解决方案(jQuery / Prototype)特别感兴趣。

15 个答案:

答案 0 :(得分:81)

仅为您的表单提供 ID ,并且仅输入名称

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

然后,访问输入元素的最符合标准且问题最少的方法是:

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

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

答案 1 :(得分:32)

  

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

当我看到元素访问的这种方法时,会想到

No-omg-never!”。这个问题是它假定DOM是一个普通的数据结构(例如:一个数组),其中元素顺序无论如何都是静态的,一致的或可靠的。我们知道99.9999%的时间,事实并非如此。在表单中重新排序或input元素,在相关表单之前向页面添加另一个form,或移动相关表单都是此代码中断的所有情况。短篇小说:这很脆弱。一旦你添加或移动某些东西,它就会破裂。

  

[2] document.myForm.foo;

我在Sergey ILinsky就是这个:

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

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

  

[3] document.getElementById('foo');

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

  

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

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


我恰好正好看video from Douglas Crockford而且他正在考虑这个问题。兴趣点在-12:00。总结一下:

  • 文档集合(document.anchor,document.form等)已过时且无关紧要(方法1)。
  • name属性用于命名事物,而不是访问它们。它用于命名窗口,输入字段和锚标记等内容。
  • “ID是您应该用来唯一标识元素的东西,以便您可以访问它。它们(名称和ID)曾经是可以互换的,但它们不再是。”

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

答案 2 :(得分:14)

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

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

答案 3 :(得分:7)

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

具体来说,对于表单:

<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 !=...

使用这种技术,该功能永远不必知道
- 页面中定义表单的顺序,
- 表格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,但它确实需要知道权重限制字段的名称。

答案 4 :(得分:6)

它并没有真正回答你的问题,只是在这一部分:

  

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

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

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

这是可访问性所必需的(例如,如果您不关联表单标签和控件,为什么这么多地讨厌盲人?)。

这有点多余,虽然当你有复选框/单选按钮时它们不那么多,其中有几个可以共享name。最终,idname用于不同目的,即使两者通常设置为相同的值。

答案 5 :(得分:4)

这有点旧,但我想添加一个我认为相关的东西 (我的意思是对上面的一个或两个线程发表评论,但似乎我需要声望50而且我在写这个时只有21个。:))
只是想说有时候通过名称而不是id来访问表单元素要好得多。我不是在谈论形式本身。表单,好的,你可以给它一个id,然后通过它访问它。但是如果你在一个表单中有一个单选按钮,那么将它作为单个对象(获取并设置其值)就更容易了,据我所知,你只能通过名字来做这件事。

例如:

<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>

您可以使用
获取/设置单选按钮R1的选中值作为整体 document.mainForm.R1.value

的document.getElementById( “MainForm的”)。R1.value
因此,如果您希望使用单一样式,则可能需要始终使用此方法,而不管表单元素的类型如何。我,我非常适合通过id访问名称和文本框的单选按钮。

答案 6 :(得分:2)

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

答案 7 :(得分:1)

name字段效果很好。它提供了对elements的引用。

parent.children-将列出所有带有父级名称字段的元素。 parent.elements-仅列出form elements,例如input-text, text-area, etc

var form = document.getElementById('form-1');
console.log(form.children.firstname)
console.log(form.elements.firstname)
console.log(form.elements.progressBar); // undefined
console.log(form.children.progressBar);
console.log(form.elements.submit); // undefined
<form id="form-1">
  <input type="text" name="firstname" />
  <input type="file" name="file" />
  <progress name="progressBar" value="20" min="0" max="100" />
  <textarea name="address"></textarea>
  <input type="submit" name="submit" />
</form>

注意:要使.elements工作,parent必须是<form> tag。而.children可以在任何HTML-element上工作-例如<div>, <span>, etc

祝你好运...

答案 8 :(得分:0)

表格2没问题,也建议使用表格3 name和id之间的冗余是由于需要保持兼容性,在html 5上一些元素(如img,form,iframe等)会丢失它们的“name”属性,并且建议从现在开始仅使用它们的id来引用它们在:)

答案 9 :(得分:0)

查看此页面:https://developer.mozilla.org/En/DOM/Document.getElementsByName

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

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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

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

如果我想将元素作为功能结构(表单)的一部分进行访问,那么我将使用:

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

从业务的角度来看,这也是如此。循环中的变化与应用程序中的功能变化一起发生,因此是有意义的。我主要将其应用于用户友好的验证,并防止网络调用检查错误的数据。我重复验证服务器端(并在其中添加更多内容),但如果我可以帮助用户客户端,那么这对所有人都有益。

对于数据汇总(比如根据表单中的数据构建饼图),我使用配置文档和自定义的Javascript对象。那么该字段的确切含义与其上下文有关,我是否使用document.getElementById()。

答案 12 :(得分:0)

只需添加上面已经说过的所有内容,就可以使用inputname来访问id,最好使用Object表单的elements属性,因为没有它,您可能会获得名为“ foo”的形式的属性,而不是HTML元素。根据@Paul D. Waite的说法,同时拥有名称和ID是完全可以的。

var myForm = document.getElementById("myform")
console.log(myForm.foo.value) // hey
console.log(myForm.foo2.value) // hey
//preferable
console.log(myForm.elements.foo.value) // hey
console.log(myForm.elements.foo2.value) // hey
<form id="myform">
  <input type="text" name="foo" id="foo2" value="hey">
</form>

根据HTMLFormElement.elements页上的MDN

  

HTMLFormElement属性元素返回一个   HTMLFormControlsCollection列出了包含在其中的所有表单控件   元素。独立地,您可以获得的数量   表单控件使用length属性。

     

您可以通过以下方式访问返回的集合中的特定表单控件:   使用索引或元素的名称 id

答案 13 :(得分:0)

我更喜欢这个

document.forms['idOfTheForm'].nameOfTheInputFiled.value;

答案 14 :(得分:0)

因为[2] document.myForm.foo是Internet Exploere的方言。 因此,我宁愿使用document.forms.myForm.elements.foodocument.forms["myForm"].elements["foo"]来代替它。