JavaScript에서 setAttribute vs.attribute =를 사용하는시기


234

setAttribute점 대신에 사용하는 것이 가장 좋습니다.. ) 속성 표기법 가 개발 되었습니까?

예 :

myObj.setAttribute("className", "nameOfClass");
myObj.setAttribute("id", "someID");

또는

myObj.className = "nameOfClass";
myObj.id = "someID";

1
에서 .setAttribute()로 전환하면 [key] = value모든 것이 마술처럼 작동하기 시작했습니다.
Andrew

답변:


73

.attributeJavaScript로 프로그래밍 방식으로 액세스하려면 항상 직접 양식을 사용해야합니다 (그러나 아래의 quirksmode 링크 참조). 다른 유형의 속성 ( "onload"라고 생각)을 올바르게 처리해야합니다.

DOM을 그대로 처리 하려면 getAttribute/를 사용하십시오 setAttribute(예 : 리터럴 텍스트 만). 다른 브라우저는 두 가지를 혼동합니다. Quirks 모드 : 속성 (in) 호환성을 참조하십시오 .


127
이 답변은 충분히 명확하지 않습니다 ... 나는 이것을 아직 이해하지 못한다고 생각합니다.
temporary_user_name

1
@ Aerovistae-이것에 동의합니다. 더 명확한 새로운 답변을 추가했습니다.
olan

1
그러나 요소의 innerHTML에 영향을 주려면 setAttribute를 사용해야합니다.
Michael

3
outterHTML * :)
megawac

4
a.href가 전체 URL을 반환하지만 getAttribute ( 'href')는 해당 속성 (<a href = "/ help"...)의 내용을 정확하게 반환합니다.
플라스틱 토끼

144

에서 자바 스크립트 : 확실한 가이드 , 그것은 일을 명확히. 그것은 것을 노트 는 HTMLElement 모든 표준 HTML에 해당하는 속성이 있다는 JS 속성을 정의한 HTML의 문서의 객체.

따라서 setAttribute비표준 속성 에만 사용해야 합니다.

예:

node.className = 'test'; // works
node.frameborder = '0'; // doesn't work - non standard attribute
node.setAttribute('frameborder', '0'); // works

2
또한 예제의 마지막 setAttribute node.frameborder가 정의되지 않은 후에 표시 되므로 값을 다시 가져 오려면 getAttribute를 사용해야합니다.
Michael

5
@Michael correct-setAttribute를 사용하여 값을 설정하는 경우 getAttribute를 사용하여 값을 검색해야합니다.
olan

3
frameBorder직접 설정하는 데 아무런 문제가 없지만 대문자 사용에 유의하십시오. 누군가 HTML 속성과 동등한 JavaScript를 camelCase하는 것이 유쾌한 아이디어라고 생각했습니다. 나는 이것에 대한 사양을 찾지 못했지만 그물은 12 가지 특정 경우 (HTML 4의 경우)에 동의하는 것 같습니다. 예를 들어 다음 게시물을 참조하십시오. drupal.org/node/1420706#comment-6423420
aaaaaaaaaaaa

1
usemap속성은 이미지에 대한 동적 맵을 생성 할 때 도트 표기법을 사용하여 설정 될 수 없다. 그것은 img.setAttribute('usemap', "#MapName");당신의 대답 usemap이 "비표준" 이라는 것을 암시합니까 ?
mseifert

1
이것은 대부분 잘못되었습니다. 일부 속성에는 속성이 정의되어 있으므로 정의하지 마십시오. 실제로 사양을 작성한 방법에 관한 것입니다. 속성이 표준인지 여부와 관계가 없습니다. 그러나 표준이 아닌 속성은 getAttribute ()를 통해서만 액세스 할 수 있습니다.
Ben

79

이전 답변 중 어느 것도 완전하지 않으며 대부분 잘못된 정보를 포함합니다.

DOM 요소 의 속성에 액세스하는 세 가지 방법이 있습니다JavaScript에서 . 세 가지 방법 모두 사용 방법을 이해하는 한 최신 브라우저에서 안정적으로 작동합니다.

1. element.attributes

요소는 속성이 속성을 라이브 그 반환 NamedNodeMap입니다Attr의이 객체를. 이 컬렉션의 색인은 브라우저마다 다를 수 있습니다. 따라서 주문이 보장되지 않습니다. NamedNodeMap속성을 추가하고 제거하는 방법이있다 ( getNamedItemsetNamedItem 각각, ).

XML은 대소 문자를 구분하지만 DOM 사양에서는 문자열 이름을 정규화 해야하므로 전달 이름 getNamedItem은 대소 문자를 구분하지 않습니다.

사용법 예 :

var div = document.getElementsByTagName('div')[0];

//you can look up specific attributes
var classAttr = div.attributes.getNamedItem('CLASS');
document.write('attributes.getNamedItem() Name: ' + classAttr.name + ' Value: ' + classAttr.value + '<br>');

//you can enumerate all defined attributes
for(var i = 0; i < div.attributes.length; i++) {
  var attr = div.attributes[i];
  document.write('attributes[] Name: ' + attr.name + ' Value: ' + attr.value + '<br>');
}

//create custom attribute
var customAttr = document.createAttribute('customTest');
customAttr.value = '567';
div.attributes.setNamedItem(customAttr);

//retreive custom attribute
customAttr = div.attributes.getNamedItem('customTest');
document.write('attributes.getNamedItem() Name: ' + customAttr.name + ' Value: ' + customAttr.value + '<br>');
<div class="class1" id="main" data-test="stuff" nonStandard="1234"></div>

2. element.getAttribute&element.setAttribute

이러한 메소드 Element는 액세스 할 필요없이 메소드와 메소드에 직접 존재 attributes하지만 동일한 기능을 수행합니다.

문자열 이름은 대소 문자를 구분하지 않습니다.

사용법 예 :

var div = document.getElementsByTagName('div')[0];

//get specific attributes
document.write('Name: class Value: ' + div.getAttribute('class') + '<br>');
document.write('Name: ID Value: ' + div.getAttribute('ID') + '<br>');
document.write('Name: DATA-TEST Value: ' + div.getAttribute('DATA-TEST') + '<br>');
document.write('Name: nonStandard Value: ' + div.getAttribute('nonStandard') + '<br>');


//create custom attribute
div.setAttribute('customTest', '567');

//retreive custom attribute
document.write('Name: customTest Value: ' + div.getAttribute('customTest') + '<br>');
<div class="class1" id="main" data-test="stuff" nonStandard="1234"></div>

3. DOM 객체의 속성 (예 : element.id

DOM 객체의 편리한 속성을 사용하여 많은 속성에 액세스 할 수 있습니다. 존재하는 속성은 HTML에 정의 된 속성이 아니라 DOM 노드의 유형에 따라 다릅니다. 속성은 해당 DOM 객체의 프로토 타입 체인에 정의되어 있습니다. 정의 된 특정 속성은 액세스중인 요소 유형에 따라 다릅니다. 예를 들어, classNameid에 정의 Element및 요소 (예.하지 텍스트 또는 주석 노드) 모든 DOM 노드에 존재합니다. 그러나 value더 좁습니다. 에 정의되어 HTMLInputElement있으며 다른 요소에는 존재하지 않을 수 있습니다.

JavaScript 속성은 대소 문자를 구분합니다. 대부분의 속성은 소문자를 사용하지만 일부는 camelCase입니다. 따라서 항상 사양을 확인하십시오.

이 "차트"는 이러한 DOM 객체에 대한 프로토 타입 체인의 일부를 캡처합니다. 완성하기에 가깝지는 않지만 전체 구조를 포착합니다.

                      ____________Node___________
                      |               |         |
                   Element           Text   Comment
                   |     |
           HTMLElement   SVGElement
           |         |
HTMLInputElement   HTMLSpanElement

사용법 예 :

var div = document.getElementsByTagName('div')[0];

//get specific attributes
document.write('Name: class Value: ' + div.className + '<br>');
document.write('Name: id Value: ' + div.id + '<br>');
document.write('Name: ID Value: ' + div.ID + '<br>'); //undefined
document.write('Name: data-test Value: ' + div.dataset.test + '<br>'); //.dataset is a special case
document.write('Name: nonStandard Value: ' + div.nonStandard + '<br>'); //undefined
<div class="class1" id="main" data-test="stuff" nonStandard="1234"></div>

주의 사항 : HTML 사양을 정의하고 최신 브라우저에서 속성을 처리하는 방법에 대한 설명입니다. 고대의 깨진 브라우저의 한계를 다루지 않았습니다. 이 정보 외에도 이전 브라우저를 지원해야하는 경우 해당 브라우저에서 무엇이 손상되었는지 알아야합니다.


이것을 정리해 주셔서 감사합니다. 어떤 버전의 IE가 '현대'로 간주되고 HTML 사양을 따르는 지 궁금합니다.
jkdev 2016 년

3
@jkdev IE는 결코 현대적이지 않습니다. 그것이 늙어가는 것.
Suraj Jain

자세한 답변을 보내 주셔서 감사합니다. DOM과 HTMLElement가 Element에서 상속하는 것과 같은 상속에 대해 많이 읽었으며 귀하의 답변은 완벽합니다.
Suraj Jain

16

setAttributeARIA 속성을 변경할 때 필요한 속성이 없기 때문에 필요한 경우를 발견했습니다 . 예를 들어

x.setAttribute('aria-label', 'Test');
x.getAttribute('aria-label');

없어 x.arialabel그런 것이 없거나 아무것도 setAttribute를 사용해야합니다.

편집 : x [ "aria-label"]이 작동하지 않습니다 . 실제로 setAttribute가 필요합니다.

x.getAttribute('aria-label')
null
x["aria-label"] = "Test"
"Test"
x.getAttribute('aria-label')
null
x.setAttribute('aria-label', 'Test2')
undefined
x["aria-label"]
"Test"
x.getAttribute('aria-label')
"Test2"

실제로 자바 스크립트가 아니라면이 x [ "aria-label"]을 할 수 있습니다
Fareed Alnamrouti

@fareednamrouti 작동하지 않습니다. 방금 테스트했습니다. JS 속성은 html 속성에 영향을 미치지 않습니다. 여기에 실제로 setAttribute가 필요합니다.
안티 모니

@Antimony이 이상하다하지만, 예를 바로 내가 투표를 할 것이다 100 %
파리 드 자카 Alnamrouti

2
ariaLabel이 없습니까?
jgmjgm

8

이 답변은 실제로 속성속성 사이의 큰 혼란을 해결하지 못합니다. . 또한 Javascript 프로토 타입에 따라 요소의 속성을 사용하여 속성에 액세스 할 수도 있고 때로는 속성에 액세스 할 수도없는 경우도 있습니다.

먼저, HTMLElement는 자바 스크립트 객체라는 것을 기억해야 합니다. 모든 객체와 마찬가지로 속성이 있습니다. 물론 원하는 거의 모든 속성을 만들 수 HTMLElement있지만 DOM (페이지의 내용)과 관련이있는 것은 아닙니다. 점 표기법 ( .)은 속성을 위한 것 입니다. 이제는 속성 에 매핑되는 몇 가지 특수 속성 이 있으며 그 시점이나 글을 쓸 때 보장되는 속성은 4 개뿐입니다 (나중에 자세히 설명).

모두 HTMLElement라는 속성이 포함되어 있습니다 attributes. HTMLElement.attributesA는 라이브 NamedNodeMap 는 DOM의 요소에 관련 개체. "실시간"은 DOM에서 노드가 변경 될 때 JavaScript 측에서 변경되고 그 반대로도 변경됨을 의미합니다. 이 경우 DOM 속성이 문제의 노드입니다. A Node에는 .nodeValue변경할 수 있는 속성이 있습니다. NamedNodeMap객체에는 setNamedItem전체 노드를 변경할 수 있는 함수 가 있습니다. 키를 사용하여 노드에 직접 액세스 할 수도 있습니다. 예를 들어, (Side note, 대소 문자를 구분하지 않으므로을 전달할 수 있음) .attributes["dir"]과 같은 것을 말할 수 있습니다 ..attributes.getNamedItem('dir');NamedNodeMap'DIR'

존재 하지 않는 노드자동으로 생성 하고 설정 하는 노드를HTMLElement 호출 할 수 있는 비슷한 기능이 있습니다 . 도 있습니다 어떤 당신이 속성으로 직접 액세스 할 수있는 속성 을 통해 특별한 속성 등은 . 다음은 모양에 대한 대략적인 매핑입니다.setAttributenodeValueHTMLElementdir

HTMLElement {
  attributes: {
    setNamedItem: function(attr, newAttr) { 
      this[attr] = newAttr;
    },    
    getNamedItem: function(attr) {
      return this[attr];
    },
    myAttribute1: {
      nodeName: 'myAttribute1',
      nodeValue: 'myNodeValue1'
    },
    myAttribute2: {
      nodeName: 'myAttribute2',
      nodeValue: 'myNodeValue2'
    },
  }
  setAttribute: function(attr, value) { 
    let item = this.attributes.getNamedItem(attr);
    if (!item) {
      item = document.createAttribute(attr);
      this.attributes.setNamedItem(attr, item);
    }
    item.nodeValue = value;
  },
  getAttribute: function(attr) { 
    return this.attributes[attr] && this.attributes[attr].nodeValue;
  },
  dir: // Special map to attributes.dir.nodeValue || ''
  id:  // Special map to attributes.id.nodeValue || ''
  className: // Special map to attributes.class.nodeValue || '' 
  lang: // Special map to attributes.lang.nodeValue || ''

}

따라서 dir속성을 6 가지 방법으로 변경할 수 있습니다 .

  // 1. Replace the node with setNamedItem
  const newAttribute = document.createAttribute('dir');
  newAttribute.nodeValue = 'rtl';
  element.attributes.setNamedItem(newAttribute);

  // 2. Replace the node by property name;
  const newAttribute2 = document.createAttribute('dir');
  newAttribute2.nodeValue = 'rtl';
  element.attributes['dir'] = newAttribute2;
  // OR
  element.attributes.dir = newAttribute2;

  // 3. Access node with getNamedItem and update nodeValue
  // Attribute must already exist!!!
  element.attributes.getNamedItem('dir').nodeValue = 'rtl';

  // 4. Access node by property update nodeValue
  // Attribute must already exist!!!
  element.attributes['dir'].nodeValue = 'rtl';
  // OR
  element.attributes.dir.nodeValue = 'rtl';

  // 5. use setAttribute()  
  element.setAttribute('dir', 'rtl');
  
  // 6. use the UNIQUELY SPECIAL dir property
  element["dir"] = 'rtl';
  element.dir = 'rtl';

당신은 방법 # 1-5 모든 속성을 업데이트,하지만 수 dir, id, lang, 및 className방법 # 6.

HTMLElement의 확장

HTMLElement그 4 가지 특별한 속성이 있습니다. 일부 요소는 HTMLElement더 많은 속성이 매핑 된 확장 클래스입니다 . 예를 들어, HTMLAnchorElementHTMLAnchorElement.href, HTMLAnchorElement.rel그리고 HTMLAnchorElement.target. 하지만, 조심 당신이 (A에서와 같이 그 특별한 속성이없는 요소에 이러한 속성을 설정하면 HTMLTableElement) 다음 속성이 변경되지 않으며 그들은 단지, 일반 사용자 정의 속성입니다. 더 잘 이해하기 위해 다음은 상속의 예입니다.

HTMLAnchorElement extends HTMLElement {
  // inherits all of HTMLElement
  href:    // Special map to attributes.href.nodeValue || ''
  target:  // Special map to attributes.target.nodeValue || ''
  rel:     // Special map to attributes.ref.nodeValue || '' 
}

맞춤 속성

이제 큰 경고 : 모든 Javascript 객체와 마찬가지로 사용자 정의 속성을 추가 할 수 있습니다. 그러나 이것들은 DOM에서 아무것도 변경하지 않습니다. 넌 할 수있어:

  const newElement = document.createElement('div');
  // THIS WILL NOT CHANGE THE ATTRIBUTE
  newElement.display = 'block';

그러나 그것은

  newElement.myCustomDisplayAttribute = 'block';

이는 사용자 정의 속성 추가 가에 연결되지 않음을.attributes[attr].nodeValue 의미합니다 .

공연

차이점을 보여주기 위해 https://jsperf.com/set-attribute-comparison jsperf 테스트 사례를 작성했습니다 . 기본적으로 순서대로 :

  1. 사용자 지정 속성은이 DOM에 영향을 미칠 수 있습니다하지 않기 때문에 속성이 없습니다 .
  2. 브라우저에서 제공하는 특별 매핑 ( dir, id, className).
  3. 속성이 이미 존재하는 경우element.attributes.ATTRIBUTENAME.nodeValue =
  4. setAttribute ();
  5. 속성이 이미 존재하는 경우element.attributes.getNamedItem(ATTRIBUTENAME).nodeValue = newValue
  6. element.attributes.ATTRIBUTENAME = newNode
  7. element.attributes.setNamedItem(ATTRIBUTENAME) = newNode

결론 (TL; DR)

  • 에서 특별한 프로퍼티 매핑을 사용하여 HTMLElement: element.dir, element.id, element.className, 또는 element.lang.

  • 요소가 HTMLElement특수 특성으로 확장 되었음을 100 % 확신하는 경우 해당 특수 맵핑을 사용하십시오. (로 확인할 수 있습니다 if (element instanceof HTMLAnchorElement)).

  • 속성이 이미 존재하는지 100 % 확신하는 경우을 사용하십시오 element.attributes.ATTRIBUTENAME.nodeValue = newValue.

  • 그렇지 않은 경우을 사용하십시오 setAttribute().


dir, id, className 및 lang의 네 가지 특성 맵핑을 언급했습니다. classList는 어떻습니까? classList는 존재하는 것이 보장되는 속성 매핑입니까?
Barzee 2016 년

classList100 % 존재한다고 보장되지만 문자열 속성이 아니며 라이브 DOMTokenList객체입니다. .className직접 설정 하는 것은 조작하는 것보다 빠르지 만 classList모든 것을 덮어 씁니다.
ShortFuse

<input> 및 <textarea> 태그의 .value는 어떻습니까? 그들은 어떤 종류입니까?
다니엘 윌리엄스

답변에서 언급 된 것은 W3C가 "IDL 속성 반영"이라고 부르는 것입니다. 를 변경하면 .value내부 값 이 변경 HTMLInputElement되어 속성에 반영됩니다. 그들은 또한 필요하지 않습니다 string. .valueAsNumber변경됩니다 value 내부적으로 , 그리고 그것의 string형태가 나타납니다 value속성. developer.mozilla.org/en-US/docs/Web/HTML/Attributes
ShortFuse

3

"JavaScript에서 setAttribute vs .attribute =를 사용하는시기?"

일반적인 규칙은 .attribute브라우저에서 작동하고 작동하는지 확인하는 것입니다.

.. 브라우저에서 작동한다면 잘 가십시오.

그렇지 않은 ..If 사용하는 .setAttribute(attribute, value)대신 .attribute에 대한 속성.

모든 속성에 대해 헹굼 반복.

글쎄, 게으른 경우 간단히 사용할 수 있습니다 .setAttribute. 대부분의 브라우저에서 잘 작동합니다. (지원하는 브라우저는 .attribute보다 최적화 할 수 있습니다 .setAttribute(attribute, value).)


0

이것은 setAttribute를 사용하는 것이 더 좋은 경우처럼 보입니다.

Dev.Opera — 효율적인 JavaScript

var posElem = document.getElementById('animation');
var newStyle = 'background: ' + newBack + ';' +
'color: ' + newColor + ';' +
    'border: ' + newBorder + ';';
if(typeof(posElem.style.cssText) != 'undefined') {
    posElem.style.cssText = newStyle;
} else {
    posElem.setAttribute('style', newStyle);
}

2
이 tomo7을 공유해 주셔서 감사합니다. 조금 더 설명해주세요. 않습니다 posElem.style = newStyle(파이어 폭스에서 나를 위해 일한) 모든 브라우저에서 작동하지? setAttribute다시 칠하지 않는 것이 바람직한 성능상의 이유 일까요? 그렇다면 posElem.style.cssText = newStyle더 많은 성능이 posElem.style = newStyle있습니까?
노티 다 르트

0

요소에서 속성 (예 : 클래스)을 설정하는 방법 : 1. el.className = 문자열 2. el.setAttribute ( 'class', string) 3. el.attributes.setNamedItem (object) 4. el.setAttributeNode (node)

간단한 벤치 마크 테스트를했습니다 ( here )

setAttributeNode는 setAttribute를 사용하는 것보다 약 3 배 빠릅니다.

따라서 성능에 문제가있는 경우 "setAttributeNode"를 사용하십시오.


크롬에서 테스트를 실행한다고 생각합니다. 크롬, 사파리 및 파이어 폭스를 사용하여 Mac에서 테스트했습니다. 이들 중 3 명은 3 가지 다른 결과를 보여주었습니다.
Olgun Kaya

0

Google API 스크립트 에서 재미있는 테이크 아웃이것에 관한 :

그들은 다음과 같이합니다 :

var scriptElement = document.createElement("script");
scriptElement = setAttribute("src", "https://some.com");
scriptElement = setAttribute("nonce", "https://some.com");
scriptElement.async = "true";

setAttribute"src"및 "nonce"와 .async = ..."async"속성에 어떻게 사용되는지 주목하십시오 .

100 % 확실하지는 않지만 "비동기"는 직접 .attr =할당 을 지원하는 브라우저에서만 지원되기 때문일 수 있습니다. 따라서 sestAttribute("async")브라우저가 이해하지 못하면 .async=..."비동기"속성을 이해 하지 못 하기 때문에 시도하는 것이 의미 가 없습니다 .

다행스럽게도 현재 진행중인 "Unminminify GAPI" 연구 프로젝트 에서 유용한 정보를 얻을 수 있기를 바랍니다 . 틀 렸으면 말해줘.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.