JavaScript에서 setAttribute vs.attribute =를 사용하는시기
setAttribute
도트 ( .
) 속성 표기법 대신 사용에 대한 모범 사례 가 개발 되었습니까?
예 :
myObj.setAttribute("className", "nameOfClass");
myObj.setAttribute("id", "someID");
또는
myObj.className = "nameOfClass";
myObj.id = "someID";
.attribute
JavaScript로 프로그래밍 방식으로 액세스하려면 항상 직접 양식을 사용해야합니다 (그러나 아래의 quirksmode 링크 참조). 다른 유형의 속성 ( "onload"라고 생각)을 올바르게 처리해야합니다.
DOM을 그대로 처리 하려면 getAttribute
/를 사용하십시오 setAttribute
(예 : 리터럴 텍스트 만). 다른 브라우저는 두 가지를 혼동합니다. Quirks modes : attribute (in) compatibility를 참조하십시오 .
에서 자바 스크립트 : 확실한 가이드 , 그것은 일을 명확히. 그것은 있다고 지적 는 HTMLElement는 모든 표준 HTML에 해당하는 속성이 있다는 JS 속성을 정의한 HTML의 문서의 객체.
따라서 setAttribute
비표준 속성 에만 사용해야 합니다.
예:
node.className = 'test'; // works
node.frameborder = '0'; // doesn't work - non standard attribute
node.setAttribute('frameborder', '0'); // works
이전 답변 중 어느 것도 완전하지 않으며 대부분 잘못된 정보를 포함합니다.
JavaScript에서 DOM 요소 의 속성에 액세스하는 세 가지 방법이 있습니다 . 세 가지 방법 모두 사용 방법을 이해하는 한 최신 브라우저에서 안정적으로 작동합니다.
1. 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>
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 객체의 프로토 타입 체인에 정의되어 있습니다. 정의 된 특정 속성은 액세스중인 요소 유형에 따라 다릅니다. 예를 들어, className
과 id
에 정의 Element
및 요소 (예.하지 텍스트 또는 주석 노드) 모든 DOM 노드에 존재합니다. 그러나 value
더 좁습니다. HTMLInputElement
다른 요소에 정의되어 있지 않을 수도 있습니다.
JavaScript 속성은 대소 문자를 구분합니다. 대부분의 속성은 소문자를 사용하지만 일부는 camelCase입니다. 따라서 항상 사양을 확인하십시오.
This "chart" captures a portion of the prototype chain for these DOM objects. It's not even close to complete, but it captures the overall structure.
____________Node___________
| | |
Element Text Comment
| |
HTMLElement SVGElement
| |
HTMLInputElement HTMLSpanElement
Example Usage:
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>
Caveat: This is an explanation of how the HTML spec defines and modern browsers handle attributes. I did not attempt to deal with limitations of ancient, broken browsers. If you need to support old browsers, in addition to this information, you will need to know what is broken in the those browsers.
One case I found where setAttribute
is necessary is when changing ARIA attributes, since there are no corresponding properties. For example
x.setAttribute('aria-label', 'Test');
x.getAttribute('aria-label');
There's no x.arialabel
or anything like that, so you have to use setAttribute.
Edit: x["aria-label"] does not work. You really do need 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"
"When to use setAttribute vs .attribute= in JavaScript?"
A general rule is to use .attribute
and check if it works on the browser.
..If it works on the browser, you're good to go.
..If it doesn't, use .setAttribute(attribute, value)
instead of .attribute
for that attribute.
Rinse-repeat for all attributes.
Well, if you're lazy you can simply use .setAttribute
. That should work fine on most browsers. (Though browsers that support .attribute
can optimize it better than .setAttribute(attribute, value)
.)
These answers aren't really addressing the large confusion with between properties and attributes. Also, depending on the Javascript prototype, sometimes you can use a an element's property to access an attributes and sometimes you can't.
First, you have to remember that an HTMLElement
is a Javascript object. Like all objects, they have properties. Sure, you can create a property called nearly anything you want inside HTMLElement
, but it doesn't have to do anything with the DOM (what's on the page). The dot notation (.
) is for properties. Now, there some special properties that are mapped to attributes, and at the time or writing there are only 4 that are guaranteed (more on that later).
All HTMLElement
s include a property called attributes
. HTMLElement.attributes
is a live NamedNodeMap
Object that relates to the elements in the DOM. "Live" means that when the node changes in the DOM, they change on the JavaScript side, and vice versa. DOM attributes, in this case, are the nodes in question. A Node
has a .nodeValue
property that you can change. NamedNodeMap
objects have a function called setNamedItem
where you can change the entire node. You can also directly access the node by the key. For example, you can say .attributes["dir"]
which is the same as .attributes.getNamedItem('dir');
(Side note, NamedNodeMap
is case-insensitive, so you can also pass 'DIR'
);
There's a similar function directly in HTMLElement
where you can just call setAttribute
which will automatically create a node if it doesn't exist and set the nodeValue
. There are also some attributes you can access directly as properties in HTMLElement
via special properties, such as dir
. Here's a rough mapping of what it looks like:
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 || ''
}
So you can change the dir
attributes 6 ways:
// 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';
You can update all properties with methods #1-5, but only dir
, id
, lang
, and className
with method #6.
Extensions of HTMLElement
HTMLElement
has those 4 special properties. Some elements are extended classes of HTMLElement
have even more mapped properties. For example, HTMLAnchorElement
has HTMLAnchorElement.href
, HTMLAnchorElement.rel
, and HTMLAnchorElement.target
. But, beware, if you set those properties on elements that do not have those special properties (like on a HTMLTableElement
) then the attributes aren't changed and they are just, normal custom properties. To better understand, here's an example of its inheritance:
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 || ''
}
Custom Properties
Now the big warning: Like all Javascript objects, you can add custom properties. But, those won't change anything on the DOM. You can do:
const newElement = document.createElement('div');
// THIS WILL NOT CHANGE THE ATTRIBUTE
newElement.display = 'block';
But that's the same as
newElement.myCustomDisplayAttribute = 'block';
This means that adding a custom property will not be linked to .attributes[attr].nodeValue
.
Performance
I've built a jsperf test case to show the difference: https://jsperf.com/set-attribute-comparison. Basically, In order:
- Custom properties because they don't affect the DOM and are not attributes.
- Special mappings provided by the browser (
dir
,id
,className
). - If attributes already exists,
element.attributes.ATTRIBUTENAME.nodeValue =
- setAttribute();
- If attributes already exists,
element.attributes.getNamedItem(ATTRIBUTENAME).nodeValue = newValue
element.attributes.ATTRIBUTENAME = newNode
element.attributes.setNamedItem(ATTRIBUTENAME) = newNode
Conclusion (TL;DR)
Use the special property mappings from
HTMLElement
:element.dir
,element.id
,element.className
, orelement.lang
.If you are 100% sure the element is an extended
HTMLElement
with a special property, use that special mapping. (You can check withif (element instanceof HTMLAnchorElement)
).If you are 100% sure the attribute already exists, use
element.attributes.ATTRIBUTENAME.nodeValue = newValue
.If not, use
setAttribute()
.
This looks like one case where it is better to use setAttribute:
Dev.Opera — Efficient 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);
}
methods for setting attributes(for example class) on an element: 1. el.className = string 2. el.setAttribute('class',string) 3. el.attributes.setNamedItem(object) 4. el.setAttributeNode(node)
I have made a simple benchmark test (here)
and it seems that setAttributeNode is about 3 times faster then using setAttribute.
so if performance is an issue - use "setAttributeNode"
참고URL : https://stackoverflow.com/questions/3919291/when-to-use-setattribute-vs-attribute-in-javascript
'IT story' 카테고리의 다른 글
액세스 토큰이 만료되는 이유는 무엇입니까? (0) | 2020.05.06 |
---|---|
새로운 자동 참조 계산 메커니즘은 어떻게 작동합니까? (0) | 2020.05.06 |
시스템 트레이에서만 실행되는 .NET Windows Forms 응용 프로그램을 만들려면 어떻게해야합니까? (0) | 2020.05.06 |
범프 버전은 무엇을 의미합니까? (0) | 2020.05.06 |
JavaScript : alert () 재정의 (0) | 2020.05.06 |