본문 바로가기

FE

1.6 속성과 프로퍼티

모던 JavaScript 튜토리얼 파트 2. 브라우저: 문서, 이벤트, 인터페이스를 읽고 정리, 기록

 

브라우저 환경과 다양한 명세서

 

브라우저 환경과 다양한 명세서

 

ko.javascript.info

 

 

브라우저는 웹페이지를 만나면 HTML을 읽어(파싱) DOM 객체를 생성한다.

요소 노드(element node)에서 대부분의 표준 HTML 속성은 DOM 객체의 프로퍼티가 된다.

아래와 같이 사용할 수 있다.

<body id=”page”>

body.id = “page”

→ 하지만 항상 1대1로 매핑되지는 않는다.

  • 속성 – HTML 안에 쓰임
  • 프로퍼티 – DOM 객체 안에 쓰임

DOM 프로퍼티

DOM 프로퍼티는 내장 프로퍼티도 많지만 자신만의 프로퍼티도 만들 수 있다.

DOM 노드는 자바스크립트 객체이다.

document.body에 새로운 프로퍼티, 메서드 만들기

document.body.myData = {
  name: 'Caesar',
  title: 'Imperator'
};

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

document.body.sayTagName();
// BODY (sayTagName의 'this'엔 document.body가 저장됨)

내장 프로토타입을 수정하여 모든 요소 노드에서 메서드 사용하게 하기

Element.prototype.sayHi = function() {
  alert(`Hello, I'm ${this.tagName}`);
};

document.documentElement.sayHi(); // Hello, I'm HTML
document.body.sayHi(); // Hello, I'm BODY

HTML 속성

HTML에서 태그는 복수의 속성을 가질 수 있다.

브라우저는 HTML을 파싱해 DOM 객체를 만들 때 HTML 표준 속성으로 DOM 프로퍼티를 만든다.

  • 표준이 아닌 속성일 때는 프로퍼티로 전환되지 않아 undefined 가 뜰 수 있다.
<body id="test" something="non-standard">
  <script>
    alert(document.body.id); // test
    // 비표준 속성은 프로퍼티로 전환되지 않습니다.
    alert(document.body.something); // undefined
  </script>
</body>

요소마다 표준 속성이 다르기 때문에 주의해야 한다.

"type"은 <input> 요소(HTMLInputElement)에선 표준이지만,

<body>(HTMLBodyElement)에선 아니다.

<body id="body" type="...">
  <input id="input" type="text">
  <script>
    alert(input.type);
    // text
    alert(body.type);
    // type은 body의 표준 속성이 아니므로 DOM 프로퍼티가 생성되지 않아 undefined 출력
  </script>
</body>

비표준 속성에 접근할 수 있는 방법

모든 속성은 아래의 메서드를 사용해 접근할 수 있다.

  • elem.hasAttribute(name) - 속성 존재 여부 확인
  • elem.getAttribute(name) - 속성값을 가져옴
  • elem.setAttribute(name, value) - 속성값을 변경함
  • elem.removeAttribute(name) - 속성값을 지움
  • elem.attributes - 모든 속성값을 읽음
    • 내장 클래스 Attr를 구현한 객체들을 담은 컬렉션을 반환
    • 객체엔 name과 value 프로퍼티가 존재한다.
<body something="non-standard">
  <script>
    alert(document.body.getAttribute('something')); // 비표준 속성에 접근
  </script>
</body>

HTML 속성의 특징

대소문자를 가리지 않는다.

값은 항상 문자열이다.

  • 예시)
<body>
  <div id="elem" about="Elephant"></div>

  <script>
    alert( elem.getAttribute('About') ); // (1) 'Elephant', 속성 읽기

    elem.setAttribute('Test', 123); // (2) 속성 추가하기

    alert( elem.outerHTML ); // (3) 추가된 속성 확인하기

    for (let attr of elem.attributes) { // (4) 속성 전체 나열하기
      alert( `${attr.name} = ${attr.value}` );
    }
  </script>
</body>

프로퍼티 - 속성 동기화

표준 속성이 변하면 대응하는 프로퍼티는 자동으로 갱신된다.

일부를 제외하고 프로퍼티가 변하면 속성 역시 갱신된다.

= 속성 ↔ 프로퍼티 간 갱신이 일어난다.

input.value 처럼 동기화가 속성 → 프로퍼티 방향으로만 일어나는 예외상황도 있다.

<input>

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

  // 속성 추가 => 프로퍼티 갱신
  input.setAttribute('value', 'text');
  alert(input.value); // text (갱신)

  // 프로퍼티를 변경해도 속성이 갱신되지 않음
  input.value = 'newValue';
  alert(input.getAttribute('value')); // text (갱신 안됨!)
</script>


DOM 프로퍼티 값의 타입

DOM 프로퍼티는 항상 문자열은 아니다.

  • 체크 박스의 input.checked 프로퍼트는 boolean 값을 가진다.
  • style 속성의 경우 문자열이지만, style 프로퍼티는 객체이다.
<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]
  alert(div.style.color); // red
</script>

DOM 프로퍼티 값이 문자열이더라도 속성값과 다른 경우도 있다.

  • href 속성이 상대 URL이나 #hash 이더라도 href 프로퍼티엔 항상 URL 전체가 저장되는 경우
link
  // 속성
  alert(a.getAttribute('href')); // #hello

  // 프로퍼티
  alert(a.href ); // 실행되는 사이트 주소에 따라 <<a href=http://site.com/page#hello>http://site.com/page#hello</a>> 형태로 값이 저장됨

비표준 속성, dataset

비표준 속성은 사용자가 직접 지정한 데이터를 HTML에서 자바스크립트로 넘기고 싶은 경우나 자바스크립트를 사용해 조작할 HTML 요소를 표시하기 위해 사용할 수 있다.

<!-- 이름(name) 정보를 보여주는 div라고 표시 -->
<div show-info="name"></div>
<!-- 나이(age) 정보를 보여주는 div라고 표시 -->
<div show-info="age"></div>

<script>
  // 표시한 요소를 찾고, 그 자리에 원하는 정보를 보여주는 코드
  let user = {
    name: "Pete",
    age: 25
  };

  for(let div of document.querySelectorAll('[show-info]')) {
    // 원하는 정보를 필드 값에 입력해 줌
    let field = div.getAttribute('show-info');
    div.innerHTML = user[field]; // Pete가 'name'에, 25가 'age'에 삽입됨
  }
</script>

요소에 스타일을 적용할 때 사용할 수도 있다.

주문 상태(order state)를 나타내는 커스텀 속성 order-state를 사용해 주문 상태에 따라 스타일을 변경

<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>

커스텀 속성의 문제점

비표준 속성을 사용해 코드를 작성했는데 나중에 속성이 표준으로 등록되게 될 수도 있다.

이런 충돌 상황을 방지하기 위한 속성인 data-* 가 있다.

 

'data-'로 시작하는 속성 전체는 개발자가 용도에 맞게 사용하도록 별도로 예약된다.

dataset 프로퍼티를 사용하면 이 속성에 접근할 수 있다.

 

  • 예시) 요소 elem에 이름이 data-about 인 속성이 있다면 elem.dataset.about 을 사용해 값을 얻을 수 있다.
<body data-about="Elephants">
<script>
  alert(document.body.dataset.about); // Elephants
</script>

data-order-state 같이 여러 단어로 구성된 속성은 카멜 표기법(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"; // (*)
</script>

data-* 속성은 커스텀 데이터를 안전하고 유효하게 전달한다.

data-* 속성을 사용하면 읽기 뿐만 아니라 수정도 가능하다.

  • 속성이 수정되면 CSS가 해당 뷰를 자동으로 업데이트
  • 위 예시에서 (*)로 표시한 줄에서 색이 파란색으로 변경됨

 

'FE' 카테고리의 다른 글

1.8 스타일과 클래스  (0) 2024.11.16
1.7 문서 수정하기  (4) 2024.11.15
1.5 주요 노드 프로퍼티 (2)  (1) 2024.11.13
1.5 주요 노드 프로퍼티 (1)  (0) 2024.11.12
1.4 getElement*, querySelector*로 요소 검색하기  (0) 2024.11.11