可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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:
<form name=\"myForm\">
<input type=\"text\" name=\"foo\" id=\"foo\" />
There are many way to access this in 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 somewhat redundant, especially if the id isn\'t necessary for any css, and increases the likelihood of typos, etc).
[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).
So what\'s best practice here? Can anyone point to something in the DOM documentation or W3C specification that could resolve this?
Note I am specifically interested in a non-library solution (jQuery/Prototype).
回答1:
Give your form an id only, and your input a name only:
<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 .foo
is preferable because the latter might return a property of the form named \"foo\" rather than a HTML element!
回答2:
[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 input
elements within the form, adding another form
to 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.
[2] document.myForm.foo;
I\'m with Sergey ILinsky on this:
- Access arbitrary elements by referring to their
id
attribute: document.getElementById(\"myform\");
- Access named form elements by name, relative to their parent form element:
document.getElementById(\"myform\").foo;
My main issue with this method is that the name
attribute 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.
[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;
In my opinion, this is acceptable, but more verbose than necessary. Method #3 is preferable.
I just so happened to be watch a video from Douglas Crockford and he weighed in on this very subject. The point of interest is at -12:00. To summarize:
- Document collections (document.anchor, document.form, etc) are obsolete and irrelevant (method 1).
- The
name
attribute 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.\"
So there you have it. Semantically, this makes the most sense.
回答3:
To access named elements placed in a form, it is a good practice to use the form
object itself.
To access an arbitrary element in the DOM tree that may on occasion be found within a form, use getElementById
and the element\'s id
.
回答4:
I much prefer a 5th method. That is
[5] Use the special JavaScript identifier this to pass the form or field object to the function from the event handler.
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
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.
回答5:
It’s not really answering your question, but just on this part:
[3] requires both an id and a name... having both is somewhat redundant
You’ll most likely need to have an id
attribute on each form field anyway, so that you can associate its <label>
element with it, like this:
<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, id
and name
are for different purposes, even if both are often set to the same value.
回答6:
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:
<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.
回答7:
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.
回答8:
Form 2 is ok, and form 3 is also recommended.
Redundancy between name and id is caused by the need to keep compatibility, on html 5 some elements (as img, form, iframe and such) will lose their \"name\" attribute, and it\'s recommended to use just their id to reference them from now on :)
回答9:
To supplement the other answers, document.myForm.foo is the so-called DOM level 0, which is the way implemented by Netscape and thus is not really an open standard even though it is supported by most browsers.
回答10:
Check out this page: https://developer.mozilla.org/En/DOM/Document.getElementsByName
document.getElementsByName(\'foo\')[0]; // returns you element.
It has to be \'elements\' and must return an array because more than one element could have the same name.
回答11:
My answer will differ on the exact question.
If I want to access a certain element specifically, then will I use document.getElementById().
An example is computing the full name of a person, because it is building on multiple fields, but it is a repeatable formula.
If I want to access the element as part of a functional structure (a form), then will I use:
var frm = document.getElementById(\'frm_name\');
for(var i = 0; i < frm.elements.length;i++){
..frm.elements[i]..
This is how it also works from the perspective of the business. Changes within the loop go along with functional changes in the application and are therefor meaningful. I apply it mostly for user friendly validation and preventing network calls for checking wrong data. I repeat the validation server side (and add there some more to it), but if I can help the user client side, then is that beneficial to all.
For aggregation of data (like building a pie chart based on data in the form) I use configuration documents and custom made Javascript objects. Then is the exact meaning of the field important in relation to its context and do I use document.getElementById().