web-dev-qa-db-ja.com

ベストプラクティス: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]は、Mozilla Geckoのドキュメントに詳しく記載されていますが、どちらも理想的ではありません。 [1]は一般的すぎて役に立たず、[3]はIDと名前の両方を必要とします(データをサーバー側の言語に投稿することを想定しています)。理想的には、id属性またはname属性のみを持つことをお勧めします(両方ともやや冗長です。特にIDがcssに不要で、タイプミスの可能性が高い場合など)。 )。

[2]は最も直感的で広く使用されているようですが、Geckoのドキュメントで参照されているのを見たことがなく、前方互換性とクロスブラウザー互換性の両方が心配です(もちろん、可能な限り準拠する標準)。

では、ここでのベストプラクティスは何ですか?誰でもこれを解決できるDOMドキュメントまたはW3C仕様の何かを指すことができますか?

注非ライブラリソリューション(jQuery/Prototype)に特に興味があります。

127
seth

フォームにidのみを指定し、入力にnameのみを指定します。

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

次に、入力要素にアクセスするための最も標準に準拠した、最も問題の少ない方法は、次の方法によるものです。

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

.elements["foo"]の代わりに.fooを使用することをお勧めします。後者は、HTML要素ではなく「foo」という名前のフォームのプロパティを返す可能性があるためです。

86
Doin

[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が望ましいです。


私はたまたま Douglas Crockfordからのビデオ を見ていたので、彼はこのまさに主題について議論しました。関心のあるポイントは-12:00です。要約する:

  • 文書コレクション(document.anchor、document.formなど)は廃止され、無関係です(方法1)。
  • name属性は、アクセスするためではなく、名前を付けるために使用されます。ウィンドウ、入力フィールド、アンカータグなどに名前を付けるためです。
  • 「IDは、要素に一意に識別してアクセスできるようにするために使用する必要があるものです。以前は(名前とID)は互換性がありましたが、もうありません。」

だからあなたはそれを持っています。意味的には、これが最も理にかなっています。

33
Justin Johnson

フォームに配置された名前付き要素にアクセスするには、formオブジェクト自体を使用することをお勧めします。

ときどきフォーム内で見つかるDOMツリーの任意の要素にアクセスするには、getElementByIdと要素のidを使用します。

14
Sergey Ilinsky

私は、5番目の方法を好みます。あれは
[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を知る必要はありませんが、重量制限フィールドの名前を知る必要はありません。

8
Robin Richmond

本当にあなたの質問に答えているわけではありませんが、この部分だけです:

[3] idと名前の両方が必要です...両方を持つことはやや冗長です

ほとんどの場合、各フォームフィールドにid属性を設定する必要があります。そのため、次のように<label>要素をそれに関連付けることができます。

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

これはアクセシビリティのために必要です(つまり、フォームラベルとコントロールを関連付けない場合、なぜ視覚障害者をそんなに嫌うのですか?)。

チェックボックス/ラジオボタンがあり、そのうちのいくつかがnameを共有できる場合は、それほど冗長ではありませんが、多少冗長です。最終的に、idnameは、両方が同じ値に設定されることが多い場合でも、目的が異なります。

7
Paul D. Waite

これは少し古いですが、関連があると思うものを追加したいと思います。
(上記の1つまたは2つのスレッドについてコメントするつもりでしたが、評判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>

を使用して、ラジオボタンR1全体のチェック値を取得/設定できます。
document.mainForm.R1.value
または
document.getElementById( "mainForm")。R1.value
したがって、統一スタイルを使用する場合は、フォーム要素のタイプに関係なく、常にこのメソッドを使用することをお勧めします。私は、名前でラジオボタンにアクセスし、IDでテキストボックスにアクセスすることに完全に満足しています。

4
VSim

昔ながらの私は常に「document.myform.myvar」構文を使用していましたが、最近Chrome(FirefoxとIEで問題ありません)で失敗しました。これはAjaxページでした(つまり、divのinnerHTMLプロパティにロードされました)。たぶんChromeはフォームをメイン文書の要素として認識しなかったかもしれません。代わりにgetElementByIdを(フォームを参照せずに)使用し、正常に機能しました。

2
Captain Nemo

フォーム2は問題なく、フォーム3も推奨されます。
[。今後それらを参照するには:)

0
wintermute

このページを確認してください: https://developer.mozilla.org/En/DOM/Document.getElementsByName

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

複数の要素が同じ名前を持つ可能性があるため、「要素」でなければならず、配列を返す必要があります。

0
robert

私の答えは正確な質問によって異なります。特定の要素に具体的にアクセスしたい場合は、document.getElementById()を使用します。例は、複数のフィールドで構築されているため、個人のフルネームを計算することですが、それは繰り返し可能な式です。

機能構造(フォーム)の一部として要素にアクセスする場合は、次を使用します。

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

これは、ビジネスの観点からも機能する方法です。ループ内の変更は、アプリケーションの機能の変更と一緒に行われるため、意味があります。私は主にユーザーフレンドリーな検証と間違ったデータをチェックするためのネットワーク呼び出しを防ぐためにそれを適用します。検証サーバー側を繰り返します(さらにそこに追加します)が、ユーザークライアント側を支援できれば、それはすべてにとって有益です。

データの集約(フォーム内のデータに基づく円グラフの作成など)には、構成ドキュメントとカスタムメイドのJavaScriptオブジェクトを使用します。次に、そのコンテキストに関連して重要なフィールドの正確な意味であり、document.getElementById()を使用します。

0
Loek Bergman

既に述べたことすべてに追加するために、inputまたはnameを使用してidsにアクセスできます。オブジェクトフォームのelementsプロパティを使用してください。 HTML要素ではなく、「foo」という名前のフォームのプロパティを取得します。 @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プロパティを使用してフォームコントロールの数だけを取得できます。

インデックスまたはエレメントのnameまたはid

これが好き

document.forms['idOfTheForm'].nameOfTheInputFiled.value;
0
Fahim Md. Riaz

他の回答を補足するために、document.myForm.fooはいわゆるDOMレベル0です。これはNetscapeによって実装される方法であり、したがってほとんどのブラウザでサポートされているにもかかわらず、実際にはオープンスタンダードではありません。

0
Kent Tong