# attribute v.s. property Attributes – is what’s written in HTML. Properties – is what’s in DOM objects. ### DOM(Document Object Model) 在DOM的標準下,一份文件中所有的標籤定義,包括文字,都是object,這些物件以文件定義的結構,形成了一個樹狀結構。 ![](https://i.imgur.com/jIM4C7s.png) DOM tree 包含 4 種節點 (parentNode,childNodes) * 文件節點 (Document node):整個文件 * 元件節點(Element node): html, head, body, ul, li… * 屬性節點(Attribute node): id, class, type… * 文本節點(text node): h1, p, span… ### HTML attributes 1. **attributes 由 HTML 定義,所有出現在 HTML 標籤內的描述皆為 attributes(standard attributes)** ```+ <div id="root" class="hello"> <!-- id, class 為 div 的 attributes --> <img src="https://i.imgur.com/AK2FguR.jpeg" alt="圖片"> <!-- src, alt 為 img 的 attributes --> </div> ``` [W3SCHOOL: img的標準 attributes](https://www.w3schools.com/tags/tag_img.asp) 2. **操作 HTML attributes** elem.hasAttribute(name) — 檢查是否有該 attribute。 elem.getAttribute(name) — 存取該 attribute。 elem.setAttribute(name, value) — 新增 attribute。 elem.removeAttribute(name) — 移除該 attribute。 elem.attributes —存取所有 attributes。 3. **所有的 attributes type 皆為 string** 4. **Their name is case-insensitive (id is same as ID). 對大小寫不敏感** ```+ <body> <div id="elem" about="Elephant"></div> <script> alert( elem.getAttribute('About') ); // (1) 'Elephant', reading elem.setAttribute('Test', 123); // (2) writing for (let attr of elem.attributes) { // (3) list all alert( `${attr.name} = ${attr.value}` ); } </script> </body> ``` ### DOM properties property屬於DOM物件,當瀏覽器加載頁面時,它解析HTML並從中生成DOM物件。 DOM實質就是javascript中的物件,因此存取 DOM properties 的方法就和存取 JavaScript 中的 object 一樣。 1. **大多數標準的HTML 特性(attributes)會自動變成DOM對象的屬性(properties)**。例如,如果標籤是 `<body id="page"> <--> body.id="page"` 3. **非標準的(自定義的) HTML attributes 並不會產生相對應的 DOM properties** ```+ <div id="test" class="button" foo="1"></div> <script> console.log(document.querySelector('#test').id); // return string: "test" console.log(document.querySelector('#test').className); // return string: "button" console.log(document.querySelector('#test').foo); // return undefined </script> ``` 3. **DOM properties 的 type 不一定是 string** [1]boolean * input.checked的property是回傳boolean值,而使用getAttribute則會回傳空字串。 ```+ <input id = "input" type = "checkbox" checked>Check Box <script> console.log(input.getAttribute('checked')); //empty string console.log(input.checked); //true </script> ``` [2]style * The style attribute is a string, but the style property is an object ```+ <div id="div" style="color:red;font-size:120%">Hello</div> <script> // string alert(div.getAttribute('style')); // color:red;font-size:120% // object alert(div.style); // [object CSSStyleDeclaration] </script> ``` [3] href * Quite rarely, even if a DOM property type is a string, it may differ from the attribute. * the href DOM property is always a full URL ```+ <a id="a" href="#hello">link</a> <script> // attribute alert(a.getAttribute('href')); // #hello // property alert(a.href ); // full URL </script> ``` 4. **DOM 物件的property 改變的時候通常對應的attribute 也會改變,但有例外=>input.value** ```+ <input> <script> let input = document.querySelector('input'); // attribute => property input.setAttribute('id', 'id'); alert(input.id); // id (updated) // property => attribute input.id = 'newId'; alert(input.getAttribute('id')); // newId (updated) </script> ``` ```+ <input> <script> let input = document.querySelector('input'); // attribute => property input.setAttribute('value', 'text'); alert(input.value); // text // NOT property => attribute input.value = 'newValue'; alert(input.getAttribute('value')); // text (not updated!) </script> ``` * Changing the attribute value updates the property. * But the property change does not affect the attribute. 5. **如果標籤上沒有設置attribute,使用getAttribute()指定該屬性會取得null,DOM物件的property會給予預設值undefined。** ```+ <input> <script> console.log(document.querySelector("input").getAttribute("ph")) // null console.log(document.querySelector("input").ph); //undefined </script> ``` ### 結論 * Attributes – is what’s written in HTML. * Properties – is what’s in DOM objects. | | Properties | Attributes | | -------- | -------- | -------- | | Type | 任何值,標準的屬性具有規範中描述的類型 | string | | Name | 對大小寫敏感的 | 對大小寫不敏感的 | > 在大多數情況下,**建議使用DOM Properties**。僅當DOM Properties無法滿足開發需求,並且我們真的需要Attributes 時才使用,例如: > * 我們想要讀取HTML中“original” value的時候,但對應的DOM Properties可能不同: href property 永遠是完整的url型式 * 用戶操作行為可能會導致value改變,在這之後,如果我們想從 HTML 中恢復“original” value,它仍然在attribute中 ### 參考資料 [Attributes and properties](https://javascript.info/dom-attributes-and-properties#property-attribute-synchronization) https://jimmyswebnote.com/html-attributes-and-dom-properties/ https://openhome.cc/Gossip/JavaScript/W3CDOM.html