답변:
.attribute
JavaScript로 프로그래밍 방식으로 액세스하려면 항상 직접 양식을 사용해야합니다 (그러나 아래의 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
node.frameborder
가 정의되지 않은 후에 표시 되므로 값을 다시 가져 오려면 getAttribute를 사용해야합니다.
frameBorder
직접 설정하는 데 아무런 문제가 없지만 대문자 사용에 유의하십시오. 누군가 HTML 속성과 동등한 JavaScript를 camelCase하는 것이 유쾌한 아이디어라고 생각했습니다. 나는 이것에 대한 사양을 찾지 못했지만 그물은 12 가지 특정 경우 (HTML 4의 경우)에 동의하는 것 같습니다. 예를 들어 다음 게시물을 참조하십시오. drupal.org/node/1420706#comment-6423420
usemap
속성은 이미지에 대한 동적 맵을 생성 할 때 도트 표기법을 사용하여 설정 될 수 없다. 그것은 img.setAttribute('usemap', "#MapName");
당신의 대답 usemap
이 "비표준" 이라는 것을 암시합니까 ?
이전 답변 중 어느 것도 완전하지 않으며 대부분 잘못된 정보를 포함합니다.
DOM 요소 의 속성에 액세스하는 세 가지 방법이 있습니다JavaScript에서 . 세 가지 방법 모두 사용 방법을 이해하는 한 최신 브라우저에서 안정적으로 작동합니다.
element.attributes
요소는 속성이 속성을 라이브 그 반환 NamedNodeMap입니다 의 Attr의이 객체를. 이 컬렉션의 색인은 브라우저마다 다를 수 있습니다. 따라서 주문이 보장되지 않습니다. NamedNodeMap
속성을 추가하고 제거하는 방법이있다 ( getNamedItem
및setNamedItem
각각, ).
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>
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>
element.id
DOM 객체의 편리한 속성을 사용하여 많은 속성에 액세스 할 수 있습니다. 존재하는 속성은 HTML에 정의 된 속성이 아니라 DOM 노드의 유형에 따라 다릅니다. 속성은 해당 DOM 객체의 프로토 타입 체인에 정의되어 있습니다. 정의 된 특정 속성은 액세스중인 요소 유형에 따라 다릅니다. 예를 들어, className
과 id
에 정의 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 사양을 정의하고 최신 브라우저에서 속성을 처리하는 방법에 대한 설명입니다. 고대의 깨진 브라우저의 한계를 다루지 않았습니다. 이 정보 외에도 이전 브라우저를 지원해야하는 경우 해당 브라우저에서 무엇이 손상되었는지 알아야합니다.
setAttribute
ARIA 속성을 변경할 때 필요한 속성이 없기 때문에 필요한 경우를 발견했습니다 . 예를 들어
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.attributes
A는 라이브 NamedNodeMap
는 DOM의 요소에 관련 개체. "실시간"은 DOM에서 노드가 변경 될 때 JavaScript 측에서 변경되고 그 반대로도 변경됨을 의미합니다. 이 경우 DOM 속성이 문제의 노드입니다. A Node
에는 .nodeValue
변경할 수 있는 속성이 있습니다. NamedNodeMap
객체에는 setNamedItem
전체 노드를 변경할 수 있는 함수 가 있습니다. 키를 사용하여 노드에 직접 액세스 할 수도 있습니다. 예를 들어, (Side note, 대소 문자를 구분하지 않으므로을 전달할 수 있음) .attributes["dir"]
과 같은 것을 말할 수 있습니다 ..attributes.getNamedItem('dir');
NamedNodeMap
'DIR'
존재 하지 않는 노드 를 자동으로 생성 하고 설정 하는 노드를HTMLElement
호출 할 수 있는 비슷한 기능이 있습니다 . 도 있습니다 어떤 당신이 속성으로 직접 액세스 할 수있는 속성 을 통해 특별한 속성 등은 . 다음은 모양에 대한 대략적인 매핑입니다.setAttribute
nodeValue
HTMLElement
dir
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
그 4 가지 특별한 속성이 있습니다. 일부 요소는 HTMLElement
더 많은 속성이 매핑 된 확장 클래스입니다 . 예를 들어, HTMLAnchorElement
이 HTMLAnchorElement.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 테스트 사례를 작성했습니다 . 기본적으로 순서대로 :
dir
, id
, className
).element.attributes.ATTRIBUTENAME.nodeValue =
element.attributes.getNamedItem(ATTRIBUTENAME).nodeValue = newValue
element.attributes.ATTRIBUTENAME = newNode
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()
.
classList
100 % 존재한다고 보장되지만 문자열 속성이 아니며 라이브 DOMTokenList
객체입니다. .className
직접 설정 하는 것은 조작하는 것보다 빠르지 만 classList
모든 것을 덮어 씁니다.
.value
의 내부 값 이 변경 HTMLInputElement
되어 속성에 반영됩니다. 그들은 또한 필요하지 않습니다 string
. .valueAsNumber
변경됩니다 value
내부적으로 , 그리고 그것의 string
형태가 나타납니다 value
속성. developer.mozilla.org/en-US/docs/Web/HTML/Attributes
"JavaScript에서 setAttribute vs .attribute =를 사용하는시기?"
일반적인 규칙은 .attribute
브라우저에서 작동하고 작동하는지 확인하는 것입니다.
.. 브라우저에서 작동한다면 잘 가십시오.
그렇지 않은 ..If 사용하는 .setAttribute(attribute, value)
대신 .attribute
에 대한 그 속성.
모든 속성에 대해 헹굼 반복.
글쎄, 게으른 경우 간단히 사용할 수 있습니다 .setAttribute
. 대부분의 브라우저에서 잘 작동합니다. (지원하는 브라우저는 .attribute
보다 최적화 할 수 있습니다 .setAttribute(attribute, value)
.)
이것은 setAttribute를 사용하는 것이 더 좋은 경우처럼 보입니다.
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);
}
posElem.style = newStyle
(파이어 폭스에서 나를 위해 일한) 모든 브라우저에서 작동하지? setAttribute
다시 칠하지 않는 것이 바람직한 성능상의 이유 일까요? 그렇다면 posElem.style.cssText = newStyle
더 많은 성능이 posElem.style = newStyle
있습니까?
요소에서 속성 (예 : 클래스)을 설정하는 방법 : 1. el.className = 문자열 2. el.setAttribute ( 'class', string) 3. el.attributes.setNamedItem (object) 4. el.setAttributeNode (node)
간단한 벤치 마크 테스트를했습니다 ( here )
setAttributeNode는 setAttribute를 사용하는 것보다 약 3 배 빠릅니다.
따라서 성능에 문제가있는 경우 "setAttributeNode"를 사용하십시오.
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" 연구 프로젝트 에서 유용한 정보를 얻을 수 있기를 바랍니다 . 틀 렸으면 말해줘.
.setAttribute()
로 전환하면[key] = value
모든 것이 마술처럼 작동하기 시작했습니다.