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

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

예 :

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

또는

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



답변

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

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


답변

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

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

예:

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


답변

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

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


답변

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"


답변

이 답변은 실제로 속성속성 사이의 큰 혼란을 해결하지 못합니다. . 또한 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().


답변

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

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

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

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

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

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


답변

이것은 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);
}