En İyi Uygulama: Form öğelerine HTML kimliğine veya ad özelliğine göre erişin?


136

Deneyimli herhangi bir JavaScript geliştiricisinin bildiği gibi, aynı şeyi yapmanın birçok (çok) yolu vardır. Örneğin, aşağıdaki gibi bir metin alanınız olduğunu varsayalım:

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

Buna JavaScript'te erişmenin birçok yolu vardır:

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

Yöntemler [1] ve [3] Mozilla Gecko belgelerinde iyi belgelenmiştir, ancak ikisi de idealdir. [1] kullanışlı olamayacak kadar geneldir ve [3] hem bir kimlik hem de bir ad gerektirir (verileri sunucu tarafı diline göndereceğiniz varsayılarak). İdeal olarak, sadece bir id özniteliğine veya bir ad özniteliğine sahip olmak en iyisidir (her ikisine birden sahip olmak, özellikle id herhangi bir css için gerekli değilse ve yazım hataları, vb. Olasılığını arttırırsa) biraz gereksizdir.

[2] en sezgisel gibi görünüyor ve yaygın olarak kullanılıyor gibi görünüyor, ancak Gecko belgelerinde referans aldığını görmedim ve hem ileriye dönük uyumluluk hem de tarayıcılar arası uyumluluk konusunda endişeliyim (ve elbette olmak istiyorum mümkün olduğunca standartlara uygun).

Peki burada en iyi uygulama nedir? Herkes DOM belgelerinde veya W3C spesifikasyonunda bunu çözebilecek bir şeye işaret edebilir mi?

Not Özellikle kütüphane olmayan bir çözüm (jQuery / Prototype) ile ilgileniyorum.


Sanırım ne kaynıyor adı özniteliğini kullanarak bir form öğesine erişmek için en standartlara uygun bir yol arıyorum ...
seth

4
"Her ikisine birden sahip olmak, özellikle id herhangi bir css için gerekli değilse ve yazım hataları olasılığını artırırsa" biraz gereksizdir. - Etiketlerin etkili kullanımı için kimlik gereklidir. Sadece CSS değil.

Bazen bir web sayfasında birden çok form vardır ve kimlik özellikleri çakışabilir.
Mart'ta Calmarius

Yanıtlar:


96

Formunuza yalnızca bir kimlik ve girişinize yalnızca bir ad verin :

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

Ardından, giriş öğenize erişmenin en standart ve en az sorunlu yolu şöyledir:

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

.elements["foo"]sadece .fooHTML yerine "foo" adlı formun bir özelliğini döndürebileceğinden , sadece yerine kullanmak tercih edilir!


1
@Karl ... Ne elde etmeye çalışıyorsun? HTML'inize JS'yi satır içine almanın oldukça yetersiz olması (ve genellikle kodun etrafında bir sarmalayıcı işlevi oluşturması nedeniyle) verimsiz olmasının yanı sıra, her zaman yanlış döndürmeniz, formunuzun asla gönderilmeyeceği anlamına gelir . Bu nedenle, formun gönderilmesi amaçlanmadığı sürece (belki de tamamen JS kodu tarafından kullanılmazsa) veya myFunc (bu) AJAX aracılığıyla göndermedikçe (ve AJAX durumunda düzenli bir gönderme yapmayı umursamıyorsanız) bir şekilde başarısız olursa), ... o zaman bir hata yaptın.
Doin

1
: Normalde, tek geçerli form verilerini göndermek için, yapacağın myform.onsubmit = validateForm;MyForm değişken form öğesi başvuran nerede (ve validateForm doğrulama işlevinin adıdır ... ama eğer bunu MyFunc adlandırabilirsiniz gerçekten , gerçekten istiyor ). Önemli olan , form geçerli olmadığında yanlış olarak kullanıcıyavalidateForm() dönmesi ve sorunlu alan (lar) ı göstermesidir. Form verileri doğru bir şekilde doğrulandığında, gönderme eyleminin devam etmesini sağlayacak şekilde true değerini döndürmelidir .
Doin

2
Form alanlarındaki kimlikleri önlemenin başka bir nedeni daha vardır: aynı formun (aynı sayfada) birden çok örneğini istemeniz durumunda.
koriander

1
De çalışır João @ sağlanan "foo" bir javascript özelliği adı olarak geçerlidir. (HTML5, nameözniteliğin değeri üzerinde neredeyse hiçbir kısıtlama getirmeyebilir , bu nedenle örneğin javascript .propertyName notasyonu kullanılarak başvurulabilir <select name="a+b">veya <input type="text" name="...2">bunlara referans verilemez). Açık [] notasyonu ayrıca ifadelerden oluşturulan adlara da izin verir, ör myCheckBox = document.getElementById("myform").elements["CHK"+i]. Artı, stilistik olarak, [] daha iyi olduğunu düşünüyorum - bu sadece bir javascript nesnesinin özellikleri olmadığını açıkça ortaya koyuyor. YMMV.
Doin

1
Linting ile ilgili olarak, linting'in sadece bir stil kılavuzu olduğunu ve linting "hatası" nın javascriptinizin geçersiz veya yanlış olduğu anlamına gelmediğini unutmayın. Bununla birlikte, bu özel durumda, linting kuralı "javascript nesne özelliklerine başvururken nokta gösterimini tercih et" demektedir. Bu iyi bir fikir ve bunu genel olarak tavsiye ediyorum. AMA linter bu fark etmiyor ise, elementsnormal bir JS nesnesi değildir ve elements.fooya elements["foo"]aslında elements.namedItem ( "foo") dönüştürülür oluyor. yani bir DOM özelliğine başvurmak yerine DOM tanımlı bir işlev çağırıyorsunuz !
Doin

34

[1] belge. Formlar [0]. Elementler [0];

Eleman erişiminin bu yöntemini gördüğümde akla " No-omg-never! " Gelir. Buradaki sorun, DOM'nin, öğe sırasının yine de statik, tutarlı veya güvenilir olduğu normal bir veri yapısı (örneğin: bir dizi) olduğunu varsaymasıdır. Zamanın% 99,9999'unun, durumun böyle olmadığını biliyoruz. inputFormdaki yeniden sıralama veya öğeler, söz konusu formdan formönce sayfaya başka bir öğe ekleme veya söz konusu formu taşıma, bu kodun kırıldığı durumlardır. Kısa öykü: bu çok kırılgan. Bir şey ekler veya taşır hareket etmez kırılır.

[2] document.myForm.foo;

Bu konuda Sergey ILinsky ile beraberim :

  • Özelliklerine bakarak rastgele öğelere erişin id:document.getElementById("myform");
  • Adlandırılmış form öğelerine, üst form öğelerine göre ada göre erişin: document.getElementById("myform").foo;

Bu yöntemle ilgili asıl sorun, namebir forma uygulandığında özniteliğin yararsız olmasıdır. Ad, POST / GET'in bir parçası olarak sunucuya iletilmez ve karma stili yer imleri için çalışmaz.

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

Bence bu en çok tercih edilen yöntem. Doğrudan erişim en kısa ve net yöntemdir.

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

Bence bu kabul edilebilir, ancak gerekenden daha ayrıntılı. Yöntem # 3 tercih edilir.


Douglas Crockford'dan bir video izledim ve bu konuya ağırlık verdi. İlgilenilen nokta -12: 00'dır. Özetlemek:

  • Belge koleksiyonları (belge.anchor, belge.form vb.) Eski ve alakasızdır (yöntem 1).
  • nameNitelik bunlara erişmek için değil, şey isim kullanılır. Pencereler, giriş alanları ve bağlantı etiketleri gibi şeyleri adlandırmak içindir.
  • "Kimlik, bir öğeyi benzersiz bir şekilde tanımlamak için kullanmanız gereken şeydir, böylece ona erişebilirsiniz. Bunlar (ad ve kimlik) birbirinin yerine kullanılabilirdi, ancak artık değiller."

İşte burada. Anlamsal olarak, bu en mantıklı.


2
Yani bu sadece bir hack mi? . document.getElementById ( "MyForm") foo; DOM'u biraz inceledikten sonra, bunun neden işe yaradığından emin değilim. Benim tahminim form nesnesi de html adı özniteliğinde dizine alt öğeleri bir dizi ...
seth

1
Ayrıca "ad sunucuya POST / GET'in bir parçası olarak geçirilmez ve karma tarzı yer imleri için çalışmaz" deyin. IS'ye sunucuya tam olarak iletilen bu değil mi? PHP ile çalışırken $ _POST global dizininizdeki name özniteliğidir.
seth

2
@ Justin, sunucuya aktarılan ad niteliğidir.
Anurag

2
@seth eski DOM gözlük neden çok belirsiz görünüyor document.aForm.fooeserler, ancak HTML5 Spec açıkça arayüzünün tanımlamak gibi görünüyor HTMLFormElementolan caller getter any namedItem(in DOMString name);. En fazla whatwg.org/specs/web-apps/current-work/multipage/...
Anurag

1
@both you guys: "... bir forma uygulandığında name özniteliği işe yaramaz ..." a'nın name özelliğinden bahsetmiyorum inputveya selecta form. Bir ismi niteliği form olmayan sunucuya geçmiş olsun.
Justin Johnson

14

Bir forma yerleştirilmiş adlandırılmış öğelere erişmek için, formnesnenin kendisini kullanmak iyi bir uygulamadır .

DOM ağacında zaman zaman bir form içinde bulunabilecek rastgele bir öğeye erişmek için öğesini getElementByIdve öğesini kullanın id.


8
"Form nesnesinin kendisini kullan" ne demek? Form nesnesine sahip olduğunuzda, belirli bir öğeye erişmek için hangi yöntemi kullanıyorsunuz?
seth

2
Adlandırılmış öğelere erişmek için N5 (document.getElementById ('myForm'). Elements.foo) ve öğelerin yinelenebilir koleksiyonuna erişmek için tavsiye ederim
Sergey Ilinsky

Kodumun stilini tanımlıyorum ... ve tercih olarak kimliklere yapışıyorum .... bu şekilde eleman erişimi sayfa boyunca tutarlı. + belirtilen diğer nedenler.

1
GetElementID kullanarak forma erişmek neden iyi bir uygulamadır? neden document.myForm çalışmıyor? (
Çalışmadığı

Hey Spundun, muhtemelen sorununuzu aylar önce çözdünüz (veya belki de ellerini yukarı kaldırdınız :)), ancak merak ediyorsanız, muhtemelen form HTML öğenize bir "isim" özniteliği vermemenizden kaynaklanıyordu.
Sheldon R.

8

5. yöntemi tercih ederim. Yani
[5] Form veya alan nesnesini olay işleyiciden işleve geçirmek için bunu özel JavaScript tanımlayıcısını kullanın .

Özellikle formlar için:

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

ve

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

Bu tekniği kullanarak, işlevin hiçbir zaman bilmek zorunda olmaması
gerekir - formların sayfada tanımlanma sırası,
- form kimliği veya
- form adı

Benzer şekilde, alanlar için:

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

ve

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

Bu durumda, işlev hiçbir zaman belirli bir ağırlık alanının adını veya kimliğini bilmek zorunda değildir, ancak ağırlık sınırı alanının adını bilmesine gerek yoktur.


Altta yatan nedenin ne olduğundan emin değilim, ama bu yaklaşımın hepsinde olmasa da bazı durumlarda boş dizeler döndürmesini sağladım.
Jacob Lee

7

Sorunuzu gerçekten cevaplamıyor, sadece bu kısımda:

[3] hem bir kimlik hem de bir isim gerektirir ... her ikisine birden sahip olmak biraz gereksizdir

Büyük olasılıkla idher form alanında bir niteliğe sahip olmanız gerekir , böylece <label>öğesini bununla ilişkilendirebilirsiniz , örneğin:

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

Erişilebilirlik için bu gereklidir (örn. Form etiketleri ve denetimleri ilişkilendirmiyorsanız, kör insanlardan neden bu kadar nefret ediyorsunuz?).

Biraz gereksizdir, ancak daha azı, birçoğunun paylaşabileceği onay kutularına / radyo düğmelerine sahip olduğunuzda name. Sonuçta idve nameher ikisi de genellikle aynı değere ayarlanmış olsa bile, farklı amaçlar içindir.


5
Bir girdiyi etiketine sararsanız, nitelik için bir kimliğe veya a'ya ihtiyacınız yoktur. <label> Foo: <giriş türü = "metin" adı = "foo" </label>
kennebec

3
Çok doğru, ancak bu görünüm ve his açısından elde edebileceğinizi sınırlıyor.
Paul D.Waite

2
@ kennebec — etiketin bir öğeyle ilişkilendirilmesini istiyorsanız her zaman bir kimlik kullanmalısınız. Orada eşleşen olmasaydı IE (<8?) Eski sürümlerinde etikete sahip bir etiket içinde değil ortak unsurları yaptığı için ve kimliği nitelikleri.
RobG

@Kennebec'un yazdıklarına ek olarak, kimliklerin kullanılması JS globalleri oluşturur ve bundan kaçınılmalıdır.
mikemaccana

1
@mikemaccana: Bunun daha önce sorunlara neden olduğunu gördüm. Kimlikleriniz makul bir şekilde açıklayıcıysa ve JavaScript'iniz makul bir şekilde adlandırılmışsa, sorunlara neden olma olasılığı düşüktür.
Paul

6

Bu biraz eski ama alakalı olduğunu düşündüğüm bir şey eklemek istiyorum.
(Yukarıdaki bir ya da 2 konu hakkında yorum yapmak istedim ama ben itibara 50 ihtiyacım var ve ben bu yazarken anda sadece 21 var gibi görünüyor. :))
Sadece erişmek için çok daha iyi zamanlar olduğunu söylemek istiyorum id yerine isme göre form öğeleri. Formun kendisinden bahsetmiyorum. Form, tamam, ona bir kimlik verebilir ve sonra ona erişebilirsiniz. Ancak bir formda radyo düğmeniz varsa, tek bir nesne olarak kullanmak (değerini almak ve ayarlamak) çok daha kolaydır ve bunu bildiğim kadarıyla sadece adıyla yapabilirsiniz.

Misal:

<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 radyo düğmesinin kontrol edilen değerini bir bütün olarak kullanarak alabilir / ayarlayabilirsiniz.
document.mainForm.R1.value
veya
document.getElementById ( "MainForm"). R1.value
bir üniter bir tarza sahip isterseniz olabilir, So form öğesinin türünden bağımsız olarak her zaman bu yöntemi kullanmak istersiniz. Ben, radyo düğmelerine ad ve metin kutularına kimliğe göre erişmek çok rahat.


İşe document.forms.mainForm.R1.valueyarayan şey, gerçekten çirkin ve sıkıcı tipte kullanmaktan kaçınmanın güzel bir yoludocument.getElementById()
Kai Carver

2

Eski moda olmak her zaman 'document.myform.myvar' sözdizimini kullandım, ancak son zamanlarda Chrome'da başarısız oldu (Firefox ve IE'de Tamam). Bir Ajax sayfasıydı (yani, div öğesinin innerHTML özelliğine yüklenmiş). Belki Chrome formu ana belgenin bir öğesi olarak tanımadı. Bunun yerine getElementById (forma başvurmadan) kullandım ve Tamam çalıştı.


sadece ekleyebilirsiniz .forms, yani document.forms.myform.myvar
Kai Carver

1

Daha önce söylenen her şeye eklemek için, inputs'ye Object formunun özelliği ile nameveya idtercihen elementsözelliğini kullanarak erişebilirsiniz , çünkü onsuz bir HTML öğesi yerine "foo" adlı bir formun özelliğini alabilirsiniz. Ve @ Paul D'ye göre. Bekleyin, hem isim hem de kimlik sahibi olmak mükemmel.

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 sayfasındaki MDN'ye göre

HTMLFormElement özellik öğeleri, öğede bulunan tüm form denetimlerini listeleyen bir HTMLFormControlsCollection döndürür. Bağımsız olarak, length özelliğini kullanarak yalnızca form denetimlerinin sayısını elde edebilirsiniz.

Dizin veya öğenin adını veya kimliğini kullanarak döndürülen koleksiyondaki belirli bir form denetimine erişebilirsiniz .


1

namealan iyi çalışıyor. Bir referans sağlar elements.

parent.children- Üst öğenin ad alanına sahip tüm öğeleri listeler. parent.elements- Sadece liste Will form elementsgibiinput-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>

Not: .elementsÇalışabilmek parentiçin a <form> tag. Halbuki, .childrenüzerinde çalışacak HTML-element- gibi <div>, <span>, etc.

İyi şanslar...


0

Form 2 iyidir ve form 3 de önerilir.
Ad ve kimlik arasındaki fazlalık, uyumluluğu koruma ihtiyacından kaynaklanır, html 5'de bazı öğeler (img, form, iframe ve benzeri gibi) "name" özniteliklerini kaybeder ve bundan sonra bunlara referans vermek için yalnızca kimliklerini kullanmaları önerilir. tarihinde :)


Görünüşe göre giriş öğeleri, sunucu tarafı dilleri tarafından kullanılma biçimi nedeniyle ad özniteliklerini asla kaybetmeyecektir. Yani soru kalır, yalnızca name özniteliğini ayarladıysanız standartlara uygun yöntem nedir?
seth

Standartlara uygun bir geliştirmede, yeni başlayanlar için sadece adınız olmazdı. Eğer gerçekten KİMİNİZ yoksa, document.getElementByName () işlevini öneririm.
kış sessiz

0

Diğer yanıtları desteklemek için document.myForm.foo, Netscape tarafından uygulanan yol olan DOM seviyesi 0'dır ve bu nedenle çoğu tarayıcı tarafından desteklenmesine rağmen gerçekten açık bir standart değildir.


4
Formlara ve form denetimlerine ad, kimlik ve dizine göre erişmek, HTML koleksiyonları için DOM 2 HTML standardının bir parçasıdır .
RobG

0

Bu sayfaya göz atın: https://developer.mozilla.org/En/DOM/Document.getElementsByName

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

Birden fazla öğe aynı ada sahip olabileceğinden, 'öğeler' olmalı ve bir dizi döndürmelidir.


@robert, şimdi bunun iyi bir çözüm olabileceğini düşünüyorum, ancak dokümanlardaki bu düzensizlik beni sinirlendirdi: "Belge türleri ve bunun için geçerli standart olmayan davranışlar arasında yukarıdaki değişiklikler göz önüne alındığında bu yöntem kullanım için şüpheli olabilir "
seth

Merhaba. Buna karşı hangi belgeler önerildi? Bence çalıştığınız tüm DOM ortamlarında xhtml kullanıyorsanız, o zaman iyi olmalısınız. Ayrıca, hangi tarayıcılar bunu desteklemiyor? IE için belgeler: msdn.microsoft.com/en-us/library/ms536438(VS.85).aspx Yukarıdaki Mozilla'ya ek olarak, başka kim desteklemeyebilir?
Robert

0

Cevabım kesin soruya göre değişecektir. Belirli bir öğeye özellikle erişmek istersem, document.getElementById () kullanacağım. Bir örnek, bir kişinin tam adını hesaplamaktır, çünkü birden fazla alan üzerine inşa edilmiştir, ancak tekrarlanabilir bir formüldür.

Eleman bir fonksiyonel yapının (form) bir parçası olarak erişmek istiyorsanız, o zaman kullanacağım:

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

Bu, işletme açısından da böyle çalışır. Döngü içindeki değişiklikler, uygulamadaki fonksiyonel değişikliklerle birlikte gider ve bunun için anlamlıdır. Bunu çoğunlukla kullanıcı dostu doğrulama ve yanlış verileri kontrol etmek için ağ çağrılarını önleme için uyguluyorum. Doğrulama sunucusu tarafını tekrar ediyorum (ve orada biraz daha ekliyorum), ancak kullanıcı istemci tarafına yardımcı olabilirsem, o zaman herkes için faydalıdır.

Verilerin toplanması için (formdaki verilere dayalı bir pasta grafik oluşturmak gibi) Yapılandırma belgelerini ve özel yapılmış Javascript nesnelerini kullanıyorum. O zaman alanın bağlamı ile ilgili anlamının tam anlamı nedir ve document.getElementById () yöntemini kullanırım.


0

Çünkü [2] document.myForm.fooörneği Internet Exploere'den bir lehçedir. Onun yerine, document.forms.myForm.elements.fooya da tercih ederim document.forms["myForm"].elements["foo"].


-1

Bunu tercih ederim

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

2
SO'ya hoş geldiniz, girişinizi takdir ediyoruz. Lütfen cevabınızı düzenleyin ve nedenini ve nasıl olduğunu açıklayın.
B - rian
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.