MDN wants to talk to developers like you: https://qsurvey.mozilla.com/s3/8d22564490d8

Custom Elements

현재 번역은 완벽하지 않습니다. 한국어로 문서 번역에 동참해주세요.

커스텀 엘리먼트들은 자신만의 커스텀 HTML 엘리멘트들을 생성하는데 유용하다. 커스텀 엘리멘트는 자체에 스크립팅된 동작과 CSS 스타일을 가질수 있다.커스텀 엘리먼트는 웹 컴포넌트들의 한 부분이지만, 또한 커스텀 엘리멘트 그 자체로도 사용할 수 있다.

Note: Custom elements have only recently stabilized, and parts of MDN still contain documentation for outdated APIs from old specification drafts.

It may be unclear as to why the new custom elements capability was created, as it was already possible to create a tag name like <mytag> and style it with CSS, then use scripting to attach behaviors to it.  커스텀 엘리멘트의 라이프 사이클에서 가지는 반응이 가지는 장점은 새로운 엘리멘트 라이프사이클에 다른 부분에 동작이 추가되는것을 허용한다. 예를들면 ,어떤 동작을 엘리멘트가 DOM으로부터 추가("connected")되거나 ,그리고 다른 DOM에서 제거될 시에("disconnected") 또는 엘리멘트의 속성이 변화시에 엘리멘트에 추가할 수있다.

The key enabler of v1 custom elements is the CustomElementRegistry.define() method, which can be used to define a new custom element. The new element will then use the supplied class for any instances, instead of the default HTMLUnknownElement. Custom elements can also be based on a native element like, <button> by using the syntax; <button is="my-button"> these are called customized built-in elements

Custom element methods

커스텀 엘리먼트가 어떻게 엘리먼트가 동작할지 제어하는 다음의  메서드를 포함한다:

constructor()
엘리먼트가 생성되거나 변경 시에 호출.
connectedCallback()
셰도우 트리를 포함한 엘리멘트가 문서(document)에 삽입될시에 호출
disconnectedCallback()
문서로부터 엘리멘트가 제거될 시에 호출
attributeChangedCallback(attributeName, oldValue, newValue, namespace)
엘리먼트의 속성이 변경, 추가, 제거, 또는 다른 엘리멘트의 교체시에 호출된다. 오로지 지켜보는 속성(observed attributes)들만 호출한다.
adoptedCallback(oldDocument, newDocument)
엘리멘트가 새로운 문서에 적용될 시 호출.

Example

커스텀 엘리먼트는 사용하기 위해서는현대적인 버전의 자바스크립트에서 도입된 class 문법(class syntax)를 필요로 한다.

HTML file:

If nothing appeared below, then your browser does not support Custom Elements yet.
<x-product data-name="Ruby" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url="http://example.com/1"></x-product>
<x-product data-name="JavaScript" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url="http://example.com/2"></x-product>
<x-product data-name="Python" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url="http://example.com/3"></x-product>

JS file:

// 엘리먼트의 클래스를 생성한다.
class XProduct extends HTMLElement {
  constructor() {
    // 항상 생성자에서 첫번재로 super를 호출해야한다.
    super();

    // 셰도우 루트를 생성한다.
    var shadow = this.attachShadow({mode: 'open'});

    // Create a standard img element and set it's attributes.
    var img = document.createElement('img');
    img.alt = this.getAttribute('data-name');
    img.src = this.getAttribute('data-img');
    img.width = '150';
    img.height = '150';
    img.className = 'product-img';

    // 셰도우 루트에 이미지를 추가한다.
    shadow.appendChild(img);

    // 이미지에 이벤트 리스너를 추가한다.
    img.addEventListener('click', () => {
      window.location = this.getAttribute('data-url');
    });

    // 상품의 링크를 추가한다.
    var link = document.createElement('a');
    link.innerText = this.getAttribute('data-name');
    link.href = this.getAttribute('data-url');
    link.className = 'product-name';

    // Add the link to the shadow root.
    shadow.appendChild(link);
  }
}

// 새로운 엘리멘트를 정의한다.
customElements.define('x-product', XProduct);

CSS file:

body {
  background: #F7F7F7;
}

x-product {
  display: inline-block;
  float: left;
  margin: 0.5em;
  border-radius: 3px;
  background: #FFF;
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  font-family: Helvetica, arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

x-product::slotted(.product-img) {
  cursor: pointer;
  background: #FFF;
  margin: 0.5em;
}

x-product::slotted(.product-name) {
  display: block;
  text-align: center;
  text-decoration: none;
  color: #08C;
  border-top: 1px solid #EEE;
  font-weight: bold;
  padding: 0.75em 0;
}

Below is the live example of the above:

Observed attributes

속성 변화를 알려주기 위해서, 엘리멘트의 클래스에 속성의 이름 배열을 리턴하는 static observedAttributes getter를 선언하여, 엘리멘트 초기화 시에 observed attributes 리스트는 정의되도록 한다.

JS file:

class HelloElement extends HTMLElement {
  // 'name' 이라는 속성의 변화를 감시한다.
  static get observedAttributes() {return ['name']; }

  // 속성의 변화에 반응한다.
  attributeChangedCallback(attr, oldValue, newValue) {
    if (attr == 'name') {
      this.textContent = `Hello, ${newValue}`;
    }
  }
}

// 새로운 엘리멘트들 정의한다.
customElements.define('hello-element', HelloElement);

HTML file:

<hello-element name="Anita"></hello-element>

Below is the live example of the above:

Specifications

Custom Elements are defined in the following specification:

Specification Status Comment
The HTML Standard: Custom elements LS  

Browser compatibility

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Basic support 49.0 No support1 No support 43.0 10.1
Feature Android Android Webview Firefox Mobile (Gecko) Firefox OS IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support 56.0 57.0 No support ? ? No support ? 53.0

1. FireFox has "dom.webcomponents.enabled" preference in about:config but even when set to true the custom elements feature is not available.

Resources

문서 태그 및 공헌자

 이 페이지의 공헌자: ByeongGi
 최종 변경: ByeongGi,