모범 사례 : HTML id 또는 이름 속성으로 양식 요소에 액세스 하시겠습니까?


136

노련한 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)에 특히 관심이 있습니다.


이름 속성을 사용하여 양식 요소에 액세스하는 가장 표준을 준수하는 방법을 찾고있는 것
같습니다

4
"두 가지를 모두 갖는 것은 특히 중복이 필요합니다. 특히 CSS에 ID가 필요하지 않은 경우 오타 가능성이 높아집니다."-레이블을 효과적으로 사용하려면 ID가 필요합니다. CSS만이 아닙니다.

때때로 웹 페이지에 여러 양식이 있고 id 속성이 충돌 할 수 있습니다.
Calmarius

답변:


96

양식에 ID 만 제공 하고 입력에 이름 만 지정하십시오.

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

그런 다음 입력 요소에 액세스하는 가장 표준을 준수하며 문제가 가장 적은 방법은 다음과 같습니다.

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

후자는 HTML 요소 대신 "foo"라는 형식의 속성을 반환 할 수 있기 때문에 .elements["foo"]그냥 대신에 사용 하는 .foo것이 좋습니다!


1
@ 칼 ... 무엇을 달성하려고합니까? JS를 HTML에 인라인하는 것은 다소 우아하지 않다는 사실 (코드 주위에 래퍼 함수를 ​​생성하기 때문에 종종 비효율적 임)을 제외하고 항상 false를 반환 한다는 사실은 양식이 절대 제출 되지 않음을 의미합니다 . 따라서 양식을 제출하지 않으려는 경우 (아마도 JS 코드에서 완전히 사용됨) 또는 myFunc (this)가 AJAX를 통해 제출하지 않는 한 (AJAX의 경우 대체로 일반 제출을 신경 쓰지 않아도됩니다) 어떻게 든 실패했습니다. ... 그러면 실수했습니다.
Doin

1
: 일반적으로 만 유효한 양식 데이터를 제출, 당신은 할 줄 myform.onsubmit = validateForm;myForm을 변수 양식 요소를 참조하는 경우 (및 validateForm는 유효성 검사 함수의 이름입니다 ...하지만 당신이 있다면 당신은 그것을 MYFUNC 이름을 지정할 수 있습니다 정말 , 정말 원하는 ). 중요한 점은 양식이 유효하지 않을 때마다 falsevalidateForm() 를 반환 하고 문제 필드를 사용자에게 표시해야한다는 것입니다. 양식 데이터가 올바르게 유효성 검증되면 제출 조치가 진행될 때 true 를 리턴해야합니다 .
Doin

2
양식 필드에서 ID를 피해야하는 또 다른 이유가 있습니다. 동일한 양식에서 동일한 양식의 여러 인스턴스를 원할 경우입니다.
koriander

1
"foo"가 자바 스크립트 속성 이름으로 유효한 경우 @ João도 작동합니다 . (이 없어야하지 않을 수 있습니다 -의 가치에 HTML5 장소 거의 제한 name속성, 그래서 당신이 가질 수있는 예 <select name="a+b">또는 <input type="text" name="...2">자바 스크립트 .propertyName 표기법을 사용하여 참조 할 수없는,). 명시 적 [] 표기법은 또한 식으로 작성된 이름을 허용합니다 (예 :) myCheckBox = document.getElementById("myform").elements["CHK"+i]. 또한 스타일 적으로는 []가 더 좋다고 생각합니다. 이것이 자바 스크립트 객체의 속성 만이 아니라는 것을 분명히합니다. YMMV.
Doin

1
린트와 관련하여, 린트는 스타일 가이드 일 뿐이며, 린트 "오류"는 자바 스크립트가 유효하지 않거나 올바르지 않다는 것을 의미하지 않습니다. 그러나이 특별한 경우에, 보푸라기 규칙이 말하는 것은 "자바 스크립트 객체 속성을 참조 할 때 점 표기법 선호"입니다. 그것은 좋은 생각이며, 일반적으로 권장합니다. 그러나 linter가 이것을 인식하지 못 하거나 elements정상적인 JS 객체가 아니며 실제로 elements.namedItem ( "foo")로 변환되고 있습니다. 즉 , JS 속성을 참조하지 않고 DOM 정의 함수를 호출하고 있습니다! elements.fooelements["foo"]
Doin

34

[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는 상호 교환이 가능했지만 더 이상은 아닙니다."

그래서 당신은 그것을 가지고 있습니다. 의미 적으로 이것은 가장 의미가 있습니다.


2
그래서 이것은 단지 해킹입니까? document.getElementById ( "myform"). foo; DOM을 꽤 연구 한 후에 왜 이것이 작동하는지 확실하지 않습니다. 내 생각 엔 폼 객체는 html name 속성에 인덱스 된 자식 요소들의 배열이다.
seth

1
또한 "이름은 POST / GET의 일부로 서버에 전달되지 않으며 해시 스타일 책갈피에는 작동하지 않습니다"라고 언급합니다. IS가 서버로 정확히 전달 된 것이 아닙니까? PHP로 작업 할 때는 $ _POST 전역의 인덱스 인 이름 속성입니다.
seth

2
@Justin, 서버에 전달되는 이름 속성입니다.
Anurag

2
@seth 오래된 DOM 사양은 이유에 대해 매우 모호 document.aForm.foo작동하지만 HTML5 스펙은 명확의 인터페이스를 정의하는 것 HTMLFormElement이있는을 caller getter any namedItem(in DOMString name);. whatwg.org/specs/web-apps/current-work/multipage/…
Anurag

1
@both 너희들 : "... 이름 속성은 폼에 적용될 때 쓸모가 없다 ..."나는 input또는 의 name 속성에 대해 말하고 있지 않다. 나는의 name 속성에 select대해 말하고있다 form. 의 이름 속성이 서버로 전달 form 되지 않습니다 .
Justin Johnson

14

양식에 배치 된 명명 된 요소에 액세스하려면 form객체 자체 를 사용하는 것이 좋습니다 .

DOM 트리에서 양식 내에서 발견 될 수있는 임의의 요소에 액세스하려면 getElementById및 요소를 사용 하십시오 id.


8
"폼 객체 자체 사용"은 무엇을 의미합니까? 양식 객체가 있으면 특정 요소에 액세스하기 위해 어떤 방법을 사용합니까?
seth

2
나는 요소의 iteratable 모음에 액세스 할 액세스라는 이름의 항목 및 N6 (. document.getElementById를 ( 'myForm을') 요소)에 N5 (. document.getElementById를 ( 'myForm을') elements.foo)를 사용하는 것이 좋습니다 의미
세르게이 Ilinsky

내 코드의 스타일을 정의하고 있으며 기본 설정으로 ID를 고수하고 있습니다 .... 페이지 전체에서 요소 액세스가 일관되게 유지됩니다. + 다른 이유들.

1
getElementID를 사용하여 양식에 액세스하는 것이 왜 좋은 방법입니까? 왜 document.myForm이 작동하지 않습니까? (저는 작동하지 않는 이유가 있습니다. 왜 그런지 궁금합니다)
Spundun

Spundun, 당신은 아마 몇 달 전에 문제를 해결했을 것입니다 (또는 아마도 손을 던졌습니다 :). 궁금한 경우 양식 HTML 요소에 "name"속성을 제공하지 않았기 때문일 것입니다.
Sheldon R.

8

나는 다섯 번째 방법을 선호합니다. 즉
[5] 식별자를 사용하여 특정 스크립트 이벤트 핸들러의 함수 형태 또는 필드 객체를 전달.

특히 양식의 경우 :

<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를 알 필요가 없지만 가중치 한계 필드의 이름을 알아야합니다.


근본 원인이 무엇인지 확실하지 않지만 일부 또는 모든 상황 에서이 방법으로 빈 문자열을 반환했습니다.
Jacob Lee

7

실제로 귀하의 질문에 대답하는 것이 아니라이 부분에만 있습니다.

[3]을 모두 갖는 ... ID와 이름을 모두 필요로 다소 중복

id어쨌든 각 양식 필드에 속성 이 있어야 하므로 다음과 같이 <label>요소를 요소와 연결할 수 있습니다 .

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

이것은 접근성을 위해 필요합니다 (즉, 양식 레이블과 컨트롤을 연결하지 않으면 왜 시각 장애인을 미워합니까?).

확인란 / 라디오 버튼이있는 경우이 옵션 중 일부가 중복되지만 다소 중복되어 있습니다 name. 궁극적으로, id그리고 name모두가 종종 같은 값으로 설정하는 경우에도, 다른 목적을위한 것입니다.


5
레이블에 입력을 줄 바꿈하면 id 또는 for 속성이 필요하지 않습니다. <label> Foo : <input type = "text"name = "foo"</ label>
kennebec

3
외관과 느낌 측면에서 달성 할 수있는 것을 제한하기는하지만 매우 사실입니다.
Paul D. Waite

2
@kennebec-라벨을 요소와 연결하려면 항상 id를 사용해야합니다. 이 일치되지 않은 경우 IE (<8?) 이전 버전의 라벨과 라벨 내부되지 동료 요소를 한 위해ID의 속성.
RobG

@kennebec이 작성한 것 외에도 ID를 사용하면 JS 전역이 생성되므로 피해야합니다.
mikemaccana

1
@ mikemaccana : 이전에 문제가 발생하는 것을 보았습니다. 귀하의 ID가 합리적으로 설명적이고 JavaScript가 네임 스페이스로 눈에 띄는 경우 문제가 발생하지 않을 것이라고 생각합니다.
Paul D. Waite

6

이것은 조금 낡았지만 관련이 있다고 생각되는 것을 추가하고 싶습니다.
(I 위의 하나 개 또는 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>


document.mainForm.R1.value
또는
document.getElementById ( "mainForm"). R1.value
를 사용하여 단일 선택 단추 R1의 값을 전체적으로 가져 오거나 설정할 수 있습니다 . 따라서 단일 스타일을 원할 수 있습니다. 양식 요소의 유형에 관계없이 항상이 방법을 사용하려고합니다. 나, 이름으로 라디오 버튼에 액세스하고 ID별로 텍스트 상자에 액세스하는 것이 완벽합니다.


작동 document.forms.mainForm.R1.value하는 것은 실제로 추악하고 지루한 유형을 사용하지 않는 좋은 방법입니다.document.getElementById()
Kai Carver

2

구식이기 때문에 항상 'document.myform.myvar'구문을 사용했지만 최근 Chrome에서 실패했습니다 (Firefox 및 IE에서 OK). Ajax 페이지였습니다 (즉, div의 innerHTML 속성에로드 됨). Chrome에서 양식을 기본 문서의 요소로 인식하지 않았을 수 있습니다. 대신 getElementById (양식을 참조하지 않고)를 사용했으며 정상적으로 작동했습니다.


당신은 단지 삽입 할 수 .forms있도록, document.forms.myform.myvar
카이 카버

1

그냥 모든 것을 추가 이미 당신이 액세스 할 수 말했다 input로 하나들 name또는 id바람직하게 사용 elements없이 당신이 "foo는"이 아닌 HTML 요소라는 형식의 속성을 가져올 수 있기 때문에, 개체 형태의 속성을. @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 속성을 사용하여 양식 컨트롤 수만 얻을 수 있습니다.

색인 또는 요소 이름 을 사용하여 반환 된 컬렉션의 특정 양식 컨트롤에 액세스 하거나 id .


1

name필드가 잘 작동합니다. 에 대한 참조를 제공합니다 elements.

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>

참고 : .elements작동 parent하려면이어야합니다 <form> tag. 반면 .children에 다음 HTML-element과 같은 작업을 수행합니다.<div>, <span>, etc .

행운을 빕니다...


0

양식 2는 괜찮으며 양식 3도 권장됩니다.
이름과 ID 사이의 중복성은 html 5에서 일부 요소 (img, form, iframe 등)가 "name"속성을 잃을 것이므로 호환성을 유지해야하기 때문에 발생합니다. 지금부터 ID를 사용하여 참조하는 것이 좋습니다 의 위에 :)


입력 요소가 서버 측 언어에서 사용되는 방식으로 인해 이름 속성을 잃지 않을 것 같습니다. 이름 속성 만 설정하면 표준 준수 방법은 무엇입니까?
seth

표준을 준수하는 개발에서는 초보자에게는 이름 만있는 것이 아닙니다. 실제로 ID를 가질 수 없다면 document.getElementByName () 함수를 제안합니다.
wintermute

0

다른 답변을 보충하기 위해 document.myForm.foo는 소위 DOM 레벨 0이며, 이는 Netscape에 의해 구현되는 방식이므로 대부분의 브라우저에서 지원되지만 실제로 공개 표준은 아닙니다.


4
이름, id 및 색인으로 양식 및 양식 제어에 액세스하는 것은 HTML 콜렉션에 대한 DOM 2 HTML 표준의 일부입니다 .
RobG

0

이 페이지를 확인하십시오 : https://developer.mozilla.org/En/DOM/Document.getElementsByName

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

'요소'여야하고 둘 이상의 요소가 같은 이름을 가질 수 있으므로 배열을 반환해야합니다.


@robert, 나는 이것이 좋은 해결책이라고 생각하고 있습니다. 그러나 문서에서 바로이 점이 저를 긴장하게 만들었습니다. "
seth

안녕. 이에 대해 어떤 문서가 제안 되었습니까? 작업중 인 모든 DOM 환경에서 xhtml을 사용하고 있다면 괜찮을 것이라고 생각합니다. 또한 어떤 브라우저가이를 지원하지 않습니까? IE에 대한 문서는 다음과 같습니다. msdn.microsoft.com/en-us/library/ms536438(VS.85).aspx 위의 Mozilla 외에도 누가 지원하지 않습니까?
robert

0

내 대답은 정확한 질문에 따라 다릅니다. 특정 요소에 구체적으로 액세스하려면 document.getElementById ()를 사용합니다. 예를 들어 사람이 여러 필드를 기반으로하고 있기 때문에 사람의 전체 이름을 계산하지만 반복 가능한 수식입니다.

기능적 구조 (양식)의 일부로 요소에 액세스하려면 다음을 사용하십시오.

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

이것이 비즈니스 관점에서도 작동하는 방식입니다. 루프 내의 변경 사항은 응용 프로그램의 기능적 변경 사항과 함께 적용되므로 의미가 있습니다. 나는 주로 사용자 친화적 인 유효성 검사 및 잘못된 데이터 확인을위한 네트워크 호출을 방지하기 위해 적용합니다. 유효성 검사 서버 쪽을 반복하고 거기에 더 추가하십시오. 그러나 사용자 클라이언트 쪽을 도울 수 있다면 모두에게 도움이됩니다.

데이터 집계를 위해 (양식의 데이터를 기반으로 원형 차트 작성과 같은) 구성 문서 및 사용자 정의 Javascript 오브젝트를 사용합니다. 그런 다음 컨텍스트와 관련하여 중요한 필드의 정확한 의미이며 document.getElementById ()를 사용합니까?


0

[2]의 경우 document.myForm.foo는 Internet Exploere의 방언이기 때문입니다. 따라서 대신 document.forms.myForm.elements.foo또는을 선호합니다 document.forms["myForm"].elements["foo"].


-1

나는 이것을 선호한다

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

2
귀하의 의견에 감사드립니다. 답을 편집하고 이유와 방법을 설명하십시오.
B--rian
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.