JavaScript - Attribute & Property

이소라·2022년 8월 17일
0

JavaScript

목록 보기
1/22

Attribute & Property

  • 브라우저는 웹페이지를 만나면 HTML을 읽어서(parsing) DOM 객체를 생성함
  • 이 때 HTML의 element 노드에서 대부분의 표준 attribute는 DOM 객체의 property가 됨
    • 예) <body id="page"> in HTML => body.id="page" in DOM
  • attribute와 property는 항상 1:1 매칭되지는 않음

DOM Property

  • DOM 노드는 JavaScript 객체임
document.body.myData = {
  name: 'Caesar',
  title: 'Imperator'
};

alert(document.body.myData.title); // Imperator

document.body.sayTagName = function() {
  alert(this.tagName); //
};

document.body.sayTagName(); // BODY (this가 document.body를 가리키므로)
  • DOM property와 메서드는 일반 JavaScript 객체와 같이 행동하므로 아래와 같은 특징을 보임
    • 어떤 값이든 가질 수 있음
    • 대소문자를 가림
      • 예) element.nodeType은 동작하지만 element.NodeType은 동작하지 않음

HTML Attribute

  • HTML에서 태그는 여러 개의 attribute를 가질 수 있음
    • 브라우저가 HTML을 파싱해 DOM 객체를 만들 때, HTML의 표준 attribute는 DOM property로 전환될 수 있음
    • 그러나 HTML의 비표준 attribute는 DOM property로 전환될 수 없음
<body id="test" something="non-standard">
  <script>
    alert(document.body.id); // test
    alert(document.body.something); // undefined
  </script>
</body>
  • 한 element에서 표준인 attribute가 다른 element에서는 표준이 아닐 수 있음
    • 예) type attribute는 <input> element에서는 표준이지만, <body>에서는 표준이 아님
    • 표준 attribute가 아닌 경우, 매핑되는 DOM property가 생성되지 않음
<body id="body" type="body">
  <input id="input" type="text" />
  <script>
    alert(input.type); // text
    alert(body.type); // undefined
  </script>
</body>
  • 표준, 비표준 속성 모두 접근할 수 있는 메서드
    • element.hasAttribute(name) : 'name' attribute의 존재 여부를 확인해주는 메서드
    • element.getAttribute(name) : 'name' attribute의 값을 가져오는 메서드
    • element.setAttribute(name, value) : 'name' attribute의 값을 'value'로 변경하는 메서드
    • element.removeAttribute(name) : 'name' attribute를 지우는 메서드
    • element.attributes : 'element'의 모든 attribute가 담긴 collection을 읽을 수 있는 메서드
      • Attr 노드를 포함한 NamedNodeMap 형 객체
      • namevalue property가 있는 객체
<body something="non-standard">
  <script>
    alert(document.body.getAttribute(something)); // non-standard
  </script>
</body>
  • HTML Attribute는 아래와 같은 특징을 가짐
    • 대소문자를 가지지 않음
      • 예) idID는 동일함
    • 값은 항상 문자열임
<body>
  <div id="elem" about="Elephant"></div>
  
  <script>
    // attribute 읽기
    alert(elem.getAttribute('About'));
    // attribute 추가하기
    elem.setAttribute('Test', 123);  
    // 추가한 attribute 확인하기
    alert(elem.outerHTML); 
    // attribute 전체 나열하기
    for (let attr of elem.attributes) {
    alert(`${attr.name} = ${attr.value}`);
    }
  </script>
</body>
  • 위 코드에서 주의할 점
    • attribute 이름은 HTML에서는 모두 소문자가 되므로 대소문자를 구분하지 않아도 됨
    • attribute의 값으로 어떤 값이든 대입할 수 있지만, 최종적으로는 문자열로 바뀜
      • 예) Test attribute의 값은 숫자 123이 아니라 문자열 "123"임
    • element.outerHTML을 사용하면 element의 직접 추가한 attribute를 포함한 모든 attribute를 볼 수 있음
    • element.attributes가 반환한 collection은 열거 가능함(iterable)
      • collection에 담긴 객체의 name, value property를 사용하여 attribute 전체에 접근 가능함

Property-Attribute 동기화

  • 표준 attribute가 변하면 대응하는 property가 자동으로 갱신됨
  • 몇몇의 경우를 제외하고 property가 변하면 attribute도 갱신됨
<input>

<script>
  let input = document.querySelector('input');

  // attribute 추가 => property 갱신
  input.setAttribute('id', 'id');
  alert(input.id); // id (갱신)

  // property 변경 => attribute 갱신
  input.id = 'newId';
  alert(input.getAttribute('id')); // newId (갱신)
</script>
  • attribute가 변하면 property가 갱신되지만, property가 변해도 attribute가 갱신되지 않는 경우도 있음
<input>

<script>
  let input = document.querySelector('input');

  // attribute 추가 => property 갱신
  input.setAttribute('value', 'text');
  alert(input.value); // text (갱신)

  // property를 변경해도 attribute이 갱신되지 않음
  input.value = 'newValue';
  alert(input.getAttribute('value')); // text (갱신 안됨!)
</script>

DOM Property 값의 type

  • DOM property는 항상 문자열이 아님
    • 대부분의 property 값의 type : string
    • input.checked property 값의 type : boolean
    • style property 값의 type : object
<input id="input" type="checkbox" checked> checkbox

<script>
  alert(input.getAttribute('checked')); // attribute 값: ''
  
  alert(input.checked); // property 값: true
</script>
<div id="div" style="color:red;font-size:120%">Hello</div>

<script>
  alert(div.getAttribute('style')); // attibute 값 : 'color:red;font-size:120%'
  
  alert(div.style); // property 값 : [object CSSStyleDeclaration]
  alert(div.style.color); // red
</script>
  • DOM propery 값이 문자열이라더라도 attribute 값과 다를 수 있음
    • 예) href attribute이 상대 URL이거나 #hash이더라도 href property에는 항상 URL 전체가 저장됨
<a id="a" href="#hello">link</a>
<script>
  alert(a.getAttribute('href')); // #hello

  alert(a.href); // http://site.com/page#hello
</script>
  • HTML에 명시된 href attribute 값을 정확하게 얻고 싶다면 element.getAttribute를 사용하기

비표준 attribute, dataset

  • 비표준 attribute 사용 예
    • 사용자가 직접 지정한 데이터를 HTML에서 JavaScript로 넘기고 싶은 경우
    • JavaScript를 사용해 조작할 HTML element를 표시하고 싶은 경우
    • element에 스타일을 적용할 때
<style>
  /* 스타일이 커스텀 속성 'order-state'에 따라 변합니다. */
  .order[order-state="new"] {
    color: green;
  }

  .order[order-state="pending"] {
    color: blue;
  }

  .order[order-state="canceled"] {
    color: red;
  }
</style>

<div class="order" order-state="new">
  A new order.
</div>

<div class="order" order-state="pending">
  A pending order.
</div>

<div class="order" order-state="canceled">
  A canceled order.
</div>
  • 비표준 attribute로 사용하면 문제가 발생할 수 있음
    • 비표준 attribute를 사용하여 코드를 작성했는데, 나중에 그 attribute가 표준으로 등록될 경우 문제가 발생함
  • 이러한 충돌 상황을 방지하기 위한 attribute : data-*
    • 'data-'로 시작하는 모든 attribute는 개발자가 용도에 맞게 사용하도록 별도로 예약됨
    • dataset property를 사용하면 'data-'로 시작하는 모든 attribute에 접근할 수 있음
<body data-about="Elephants">
<script>
  alert(document.body.dataset.about); // Elephants
</script>
  • data-* attribute

    • 커스텀 데이터를 안전하고 유효가게 전달해줌
    • 읽기와 수정이 가능함
    • attribute가 수정되면 CSS가 해당 뷰를 자동으로 업데이트함
  • data-order-state와 같이 여러 단어로 구성된 attribute는 카멜 표기법(camel-cased)을 사용하여 dataset.orderState로 변환됨

<style>
  .order[data-order-state="new"] {
    color: green;
  }

  .order[data-order-state="pending"] {
    color: blue;
  }

  .order[data-order-state="canceled"] {
    color: red;
  }
</style>

<div id="order" class="order" data-order-state="new">
  A new order.
</div>

<script>
  // 읽기
  alert(order.dataset.orderState); // new

  // 수정하기
  order.dataset.orderState = "pending"; // order div의 CSS color가 blue가 됨
</script>

Summary

AttributeProperty
HTML에서 사용됨DOM 객체에서 사용됨
value문자열모든 타입이 가능함
name대소문자 구분하지 않음대소문자 구분함

0개의 댓글