Javascript 最佳实践:通过 HTML id 或 name 属性访问表单元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2435525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:18:50  来源:igfitidea点击:

Best Practice: Access form elements by HTML id or name attribute?

javascripthtmlformsdom

提问by seth

As any seasoned JavaScript developer knows, there are many (too many) ways to do the same thing. For example, say you have a text field as follows:

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

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

There are many way to access this in JavaScript:

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

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

Methods [1] and [3] are well documented in the Mozilla Gecko documentation, but neither are ideal. [1] is just too general to be useful and [3] requires both an id and a name (assuming you will be posting the data to a server side language). Ideally, it would be best to have only an id attribute or a name attribute (having both is somewhatredundant, especially if the id isn't necessary for any css, and increases the likelihood of typos, etc).

方法 [1] 和 [3] 在 Mozilla Gecko 文档中有详细记录,但都不是理想的。[1] 太笼统而没有用,[3] 需要一个 id 和一个名称(假设您将数据发布到服务器端语言)。理想情况下,最好只有一个 id 属性或一个 name 属性(同时拥有这两个属性有点多余,特别是如果 id 对于任何 css 都不是必需的,并且会增加拼写错误的可能性等)。

[2] seems to be the most intuitive and it seems to be widely used, but I haven't seen it referenced in the Gecko documentation and I'm worried about both forwards compatibility and cross browser compatiblity (and of course I want to be as standards compliant as possible).

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

So what's best practice here? Can anyone point to something in the DOM documentation or W3C specification that could resolve this?

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

Note I am specifically interested in a non-library solution (jQuery/Prototype).

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

回答by Doin

Give your form an idonly, and your input a nameonly:

只给你的表单一个id,你只输入一个名称

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

Then the most standards-compliant and least problematic way to access your input element is via:

那么访问输入元素的最符合标准且问题最少的方法是通过:

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

using .elements["foo"]instead of just .foois preferable because the latter might return a property of the form named "foo" rather than a HTML element!

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

回答by Justin Johnson

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

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

"No-omg-never!" comes to mind when I see this method of element access. The problem with this is that it assumes that the DOM is a normal data structure (e.g.: an array) wherein the element order is static, consistent or reliable in anyway. We know that 99.9999% of the time, that this is not the case. Reordering or inputelements within the form, adding another formto the page before the form in question, or moving the the form in question are all cases where this code breaks. Short story: this is very fragile. As soon as you add or move something, it's going to break.

No-omg-never!”当我看到这种元素访问方法时,我想到了。问题在于它假设 DOM 是一个普通的数据结构(例如:数组),其中元素顺序无论如何都是静态的、一致的或可靠的。我们知道 99.9999% 的情况并非如此。重新排序或input表单中的元素,form在有问题的表单之前向页面添加另一个元素,或移动有问题的表单都是此代码中断的所有情况。小故事:这是非常脆弱的。一旦您添加或移动某些东西,它就会损坏。

[2] document.myForm.foo;

[2] document.myForm.foo;

I'm with Sergey ILinskyon this:

我和谢尔盖·伊林斯基在一起

  • Access arbitrary elements by referring to their idattribute: document.getElementById("myform");
  • Access named form elements by name, relative to their parent form element: document.getElementById("myform").foo;
  • 通过引用它们的id属性来访问任意元素:document.getElementById("myform");
  • 按名称访问命名的表单元素,相对于它们的父表单元素: document.getElementById("myform").foo;

My main issue with this method is that the nameattribute is useless when applied to a form. The name is not passed to the server as part of the POST/GET and doesn't work for hash style bookmarks.

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

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

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

In my opinion, this is the most preferable method. Direct access is the most concise and clear method.

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

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

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

In my opinion, this is acceptable, but more verbose than necessary. Method #3 is preferable.

在我看来,这是可以接受的,但过于冗长。方法#3 更可取。



I just so happened to be watch a video from Douglas Crockfordand he weighed in on this very subject. The point of interest is at -12:00. To summarize:

我碰巧观看了道格拉斯·克罗克福德 (Douglas Crockford)视频,他就这个问题发表了意见。兴趣点是-12:00。总结一下:

  • Document collections (document.anchor, document.form, etc) are obsolete and irrelevant (method 1).
  • The nameattribute is used to name things, not to access them. It is for naming things like windows, input fields, and anchor tags.
  • "ID is the thing that you should use to uniquely identify an element so that you can get access to it. They (name and ID) used to be interchangeable, but they aren't anymore."
  • 文档集合(document.anchor、document.form 等)已过时且无关紧要(方法 1)。
  • name属性用于命名事物,而不是访问它们。它用于命名诸如窗口、输入字段和锚标记之类的东西。
  • “ID 是你应该用来唯一标识一个元素以便你可以访问它的东西。它们(名称和 ID)曾经是可以互换的,但它们不再是了。”

So there you have it. Semantically, this makes the most sense.

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

回答by Sergey Ilinsky

To access named elements placed in a form, it is a good practice to use the formobject itself.

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

To access an arbitrary element in the DOM tree that may on occasion be found within a form, use getElementByIdand the element's id.

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

回答by Robin Richmond

I much prefer a 5th method. That is
[5] Use the special JavaScript identifier thisto pass the form or field object to the function from the event handler.

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

Specifically, for forms:

具体来说,对于表格:

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

and

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

Using this technique, the function never has to know
- the order in which forms are defined in the page,
- the form ID, nor
- the form name

使用这种技术,函数永远 不必知道
- 在页面中定义表单的顺序,
- 表单 ID,也不需要
- 表单名称

Similarly, for fields:

同样,对于字段:

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

and

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

In this case, the function never has to know the name or id of a particular weight field, though it does need to know the name of the weight limit field.

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

回答by Paul D. Waite

It's not really answering your question, but just on this part:

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

[3] requires both an id and a name... having both is somewhatredundant

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

You'll most likely need to have an idattribute on each form field anyway, so that you can associate its <label>element with it, like this:

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

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

This is required for accessibility (i.e. if you don't associate form labels and controls, why do you hate blind people so much?).

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

It is somewhat redundant, although less so when you have checkboxes/radio buttons, where several of them can share a name. Ultimately, idand nameare for different purposes, even if both are often set to the same value.

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

回答by VSim

This is a bit old but I want to add a thing I think is relevant.
(I meant to comment on one or 2 threads above but it seems I need reputation 50 and I have only 21 at the time I'm writing this. :) )
Just want to say that there are times when it's much better to access the elements of a form by name rather than by id. I'm not talking about the form itself. The form, OK, you can give it an id and then access it by it. But if you have a radio button in a form, it's much easier to use it as a single object (getting and setting its value) and you can only do this by name, as far as I know.

Example:

这有点旧,但我想添加一个我认为相关的内容。
(我想对上面的一两个线程发表评论,但似乎我需要声望 50,而在我写这篇文章的时候我只有 21。:))
只是想说,有时候访问表单元素按名称而不是 id。我不是在谈论表格本身。表单,OK,你可以给它一个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>

You can get/set the checked value of the radio button R1 as a whole by using
document.mainForm.R1.value
or
document.getElementById("mainForm").R1.value
So if you want to have a unitary style, you might want to always use this method, regardless of the type of form element. Me, I'm perfectly comfortable accessing radio buttons by name and text boxes by id.

您可以通过使用
document.mainForm.R1.value

document.getElementById("mainForm").R1.value整体获取/设置单选按钮 R1 的选中值
所以如果你想要一个单一的样式,你可能无论表单元素的类型如何,都希望始终使用此方法。我,我非常喜欢按名称访问单选按钮和按 id 访问文本框。

回答by Captain Nemo

Being old-fashioned I've always used the 'document.myform.myvar' syntax but I recently found it failed in Chrome (OK in Firefox and IE). It was an Ajax page (i.e. loaded into the innerHTML property of a div). Maybe Chrome didn't recognise the form as an element of the main document. I used getElementById (without referencing the form) instead and it worked OK.

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

回答by Jo?o Pimentel Ferreira

Just to add to everything already said, you may access the inputs either with the nameor idusing preferably the elementsproperty of the Object form, because without it you may get a property of the form named "foo" rather than an HTML element. And according to @Paul D. Waite it's perfectly ok to have both name and id.

为了补充已经说过的所有内容,您可以使用或最好使用Object 表单的属性来访问inputs ,因为如果没有它,您可能会获得名为“foo”的表单属性而不是 HTML 元素。根据@Paul D. Waite 的说法,拥有姓名和 ID 是完全可以的。nameidelements

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>

According to MDN on the HTMLFormElement.elementspage

根据HTMLFormElement.elements页面上的 MDN

The HTMLFormElement property elements returns an HTMLFormControlsCollection listing all the form controls contained in the element. Independently, you can obtain just the number of form controls using the length property.

You can access a particular form control in the returned collection by using either an index or the element's nameor id.

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

您可以使用索引或元素的名称id访问返回集合中的特定表单控件。

回答by Akash

namefield works well. It provides a reference to the elements.

name领域运作良好。它提供了对elements.

parent.children- Will list all elements with a name field of the parent. parent.elements- Will list only form elementssuch as input-text, text-area, etc

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>

Note: For .elementsto work, the parentneeds to be a <form> tag. Whereas, .childrenwill work on any HTML-element- such as <div>, <span>, etc.

注意:为了.elements工作,parent需要是一个<form> tag. 而,.children将适用于任何HTML-element- 例如<div>, <span>, etc.

Good Luck...

祝你好运...

回答by takahar tanak

Because the case [2] document.myForm.foois a dialect from Internet Exploere. So instead of it, I prefer document.forms.myForm.elements.fooor document.forms["myForm"].elements["foo"].

因为案例 [2]document.myForm.foo是来自 Internet Exploere 的方言。因此,我更喜欢document.forms.myForm.elements.fooor document.forms["myForm"].elements["foo"]