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

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

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

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

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

258601 次浏览

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

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

表格2可以,表格3也可以。

姓名身份证之间的冗余是由于需要保持兼容性而造成的。在 HTML5中,一些元素(如 IMG表格Iframe等)将失去它们的“ name”属性,建议从现在开始只使用它们的 身份证来引用它们:)

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

当我看到这种元素访问方法时,脑海中浮现出“ 绝对不行!”。这样做的问题在于,它假设 DOM 是一个正常的数据结构(例如: 一个数组) ,其中的元素顺序是静态的、一致的或者可靠的。我们知道在99.9999% 的情况下,事实并非如此。在表单中重新排序或者 input元素,在有问题的表单之前向页面添加另一个 form,或者移动有问题的表单,这些都是代码中断的情况。短篇小说: 这是非常脆弱的。只要你添加或移动一些东西,它就会破裂。

[2] document. myForm.foo;

我同意 谢尔盖 · 伊林斯基的观点:

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

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

[3] document. getElementById (‘ foo’) ;

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

[4] document.getElementById (‘ myForm’) . foo;

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


我刚好在看 道格拉斯·克罗克福特的视频他就这个话题发表了看法。兴趣点在 -12:00。总结一下:

  • 文档集合(Document.Anchor、 Document.form 等)已经过时且无关紧要(方法1)。
  • name属性用于命名事物,而不是访问它们。它用于命名诸如窗口、输入字段和锚标记之类的东西。
  • ”ID 是您应该用来唯一标识一个元素的东西,这样您就可以访问它。他们(姓名和身份证)过去是可以互换的,但现在不再是了。”

就是这样,从语义上讲,这是最有意义的。

看看这个页面: < a href = “ https://developer.mozilla.org/En/DOM/Document.getElementsByName”rel = “ nofollow noReferrer”> Document.getElementsByName ()

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

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

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

[3]要求同时具有 id 和 name... 两者都是 有点冗余

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

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

这是可访问性所必需的(也就是说,如果您不将表单标签和控件关联起来,那么为什么您这么讨厌盲人呢?).

它有点多余,但是当您有复选框/单选按钮(其中几个按钮可以共享一个 name)时就不那么多余了。最终,idname用于不同的目的,即使两者通常设置为相同的值。

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

我更喜欢第五种方法
[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 !=...

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

由于过时,我一直使用“ document.myform.myvar”语法,但最近我发现它在 Chrome 中失败了(在 Firefox 和 IE 中都是 OK)。它是一个 Ajax 页面(即加载到 div 的 innerHTML 属性中)。也许 Chrome 没有把表单作为主文档的一个元素。我使用 getElementById (没有引用表单)代替,它工作正常。

对于确切的问题,我的答案将有所不同。 如果我特别想访问某个元素,那么我将使用 document.getElementById ()。 一个例子是计算一个人的全名,因为它是在多个字段上构建的,但它是一个可重复的公式。

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

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

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

对于数据聚合(比如基于表单中的数据构建饼图) ,我使用配置文档和定制的 JavaScript 对象。那么字段的确切含义对于它的上下文是否重要以及我是否使用 document.getElementById ()。

只给你的表格一个 身份证,输入一个 姓名:

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

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

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

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

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

示例: < br/>

<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作为一个整体的检查值
R1.value
或者
GetElementById (“ mainForm”) . R1.value
因此,如果希望使用酉样式,则可能希望始终使用此方法,而不管表单元素的类型如何。至于我,我完全可以通过名称访问单选按钮,通过 id 访问文本框。

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

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>

根据 元素页面上的 MDN

HTMLFormElement 属性元素返回一个 中包含的所有窗体控件 元素。独立地,您可以获得 使用 length 属性的窗体控件。

可以通过以下方法访问返回集合中的特定窗体控件 使用索引或元素的 姓名身份证

我更喜欢 这个:

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

name属性工作得很好,它提供了对 elements的引用。

parent.children-将列出具有父元素的名称字段的所有元素。 将只列出 form elements,如 input-texttext-area等。

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>标记。然而,.children可以处理任何 HTML 元素,比如 <div><span>等等。

因为这个 case [2] abc 0是一种来自 Internet Explorer 的方言。

所以我更喜欢 document.forms.myForm.elements.foo或者 document.forms["myForm"].elements["foo"]

旧问题,新见解(2021)

在阅读和学习了一些优秀的答案,这个问题,是需要回到基础上,尝试 来获取更多的数据如何 idname定义在他们的起源

结果很简单,很有启发性,我总结如下:


  • 最重要的事实是,到目前为止,ABC0和 name是如此不同,有如此不同的目的,他们是 W3/WHATWG 规范的 在不同的章节中定义。简而言之:
    • 返回文章页面
      • 定义为 DOM (web 文档标准)规范的一部分,而不是作为 HTML (标记语言)的东西。
      • 它的用途是 直接相关的唯一标识文档中的一个节点。因此,非常适合于 接达节点
      • 必须是独一无二的
    • 返回文章页面
      • 定义为 HTML 规范的一部分,而不是 DOM 和 DOM
      • 它的用途是与 提交表格相关的 直接——表单的结构、它的 enctype、发送到服务器的数据(例如通过 https)等等。

  • 基于上述数据和作为开发人员积累的一些经验,我的主要结论是:
    1. 关于使用 idname访问 元素 是由一些主要因素造成的的混淆:
      • 虽然术语 元素在 DOM 规范中有明确的定义,但是在 HTML 规范中没有非常明确的定义——它指的是 DOM、 xhtml 名称空间等等。
      • 我们,开发人员,不喜欢钻研定义的技术细节(也许我不需要在这里详细说明这个假设) ,这可能会导致进一步的误解。
      • 因此,术语 元素被广泛用于指代 HTML 标记(例如,form)和 DOM 节点(尽管事实上 form是 DOM 中的节点,但反之亦然)
      • JavaScript 提供了许多方法来访问 DOM 中的 事情,包括那些基于自身内容的方法,比如(getElementsBy标签名称,getElements字幕) ,它需要一些幕后操作来从 DOM 中检索实际的 节点
      • 一方面,它使开发人员更容易访问这些 元素; 另一方面,它隐藏了在特定上下文中扮演重要角色的概念和结构。
      • 最终,上述因素产生混乱,导致必要的和聪明的问题,如一个创始整个线程。
    2. 在阅读了答案和评论,收集了数据,通过分析数据和得出结论烧毁了一些神经元之后,我对这个问题的回答是:
      • 如果你想保持它严格的技术性(并且可能在性能上有所提高) ,那么尽可能使用 id,这样做是有意义的——例如,在任何地方添加 id都是没有意义的; 在 radio输入类型中使用 id属性可能也是没有意义的。
      • 如果您希望使用 JavaScript 提供的灵活性,但同时兼顾两方面的优点,我建议使用 @ Doin 在此线程中提供的解决方案
      • 我也很欣赏 @ paul-d-waite带来的可及性因素,同样的因素也在 这个的答案中被探讨。
      • 记住,不是所有你能做到的事情都应该做到。

参考文献:

  1. HTML-name
  2. HTML-element
  3. DOM-id
  4. DOM-element
  5. HTML-生活标准ー2021年11月5日最后更新
  6. DOM-生活标准ー最近更新于2021年10月18日

看看 form元素也是值得的


Stackoverflow 的其他参考文献:

在 html 中真的需要 name 属性吗?

HTML 中 id 和 name 属性的区别


奖励: ABC0和 name之间短暂而冷静的区别,对于不耐烦的人来说。