[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/ja/docs/Web/API/Web_components/Using_custom_elements [Back]  [Original]

- Web API | MDN

MDN Web Docs

View in English Always switch to English

HTML

2

  • JavaScript
  • HTML JavaScript

HTMLElement HTML document.createElement() DOM

<p>

js
class WordCount extends HTMLParagraphElement {
  constructor() {
    super();
  }
  // 
}

js
class PopupInfo extends HTMLElement {
  constructor() {
    super();
  }
  // 
}

Requirements for custom element constructors and reactions

  • connectedCallback():
  • disconnectedCallback():
  • connectedMoveCallback(): connectedCallback() disconnectedCallback() Element.moveBefore() DOM DOM connectedCallback() disconnectedCallback() /
  • adoptedCallback():
  • attributeChangedCallback():

js
// 
class MyCustomElement extends HTMLElement {
  static observedAttributes = ["color", "size"];

  constructor() {
    //  super 
    super();
  }

  connectedCallback() {
    console.log("");
  }

  disconnectedCallback() {
    console.log("");
  }

  connectedMoveCallback() {
    console.log(" moveBefore() ");
  }

  adoptedCallback() {
    console.log("");
  }

  attributeChangedCallback(name, oldValue, newValue) {
    console.log(` ${name} `);
  }
}

customElements.define("my-custom-element", MyCustomElement);

DOM HTML

Element.moveBefore() Node.insertBefore() disconnectedCallback() connectedCallback() DOM

connectedMoveCallback() Element.moveBefore() Node.insertBefore() connectedMoveCallback() connectedCallback() disconnectedCallback()

connectedMoveCallback() 2

js
class MyComponent {
  // ...
  connectedMoveCallback() {
    console.log("");
  }
  // ...
}

Window.customElements define()

define()

name

definition of a valid name

constructor

options

extends

WordCount

js
customElements.define("word-count", WordCount, { extends: "p" });

PopupInfo

js
customElements.define("popup-info", PopupInfo);

is

html
<p is="word-count"></p>

HTML

html
<popup-info>
  <!--  -->
</popup-info>

HTML

  • observedAttributes
  • attributeChangedCallback()

attributeChangedCallback() observedAttributes

3

size

js
// 
class MyCustomElement extends HTMLElement {
  static observedAttributes = ["size"];

  constructor() {
    super();
  }

  attributeChangedCallback(name, oldValue, newValue) {
    console.log(
      ` ${name}  ${oldValue}  ${newValue} `,
    );
  }
}

customElements.define("my-custom-element", MyCustomElement);

HTML attributeChangedCallback() DOM attributeChangedCallback()

html
<my-custom-element size="100"></my-custom-element>

attributeChangedCallback()

CSS

HTML HTML JavaScript CSS

:state() "collapsed"

collapsed CSS HTMLElement.attachInternals() ElementInternals ElementInternals.states CustomStateSet true CustomStateSet hidden false hidden collapsed

js
class MyCustomElement extends HTMLElement {
  constructor() {
    super();
    this._internals = this.attachInternals();
  }

  get collapsed() {
    return this._internals.states.has("hidden");
  }

  set collapsed(flag) {
    if (flag) {
      //  "true" 
      this._internals.states.add("hidden");
    } else {
      //  "false" 
      this._internals.states.delete("hidden");
    }
  }
}

// 
customElements.define("my-custom-element", MyCustomElement);

CustomStateSet (this._internals.states) :state() hidden hidden truecollapsed

css
my-custom-element {
  border: dashed red;
}
my-custom-element:state(hidden) {
  border: none;
}

:state() :host() DOM :state() ::part()

CustomStateSet

web-components-examples https://mdn.github.io/web-components-examples/

<popup-info>

HTMLElement PopupInfo JavaScript

js
// 
class PopupInfo extends HTMLElement {
  constructor() {
    //  super 
    super();
  }

  connectedCallback() {
    // 
    const shadow = this.attachShadow({ mode: "open" });

    // span 
    const wrapper = document.createElement("span");
    wrapper.setAttribute("class", "wrapper");

    const icon = document.createElement("span");
    icon.setAttribute("class", "icon");
    icon.setAttribute("tabindex", 0);

    const info = document.createElement("span");
    info.setAttribute("class", "info");

    //  span 
    const text = this.getAttribute("data-text");
    info.textContent = text;

    // 
    let imgUrl;
    if (this.hasAttribute("img")) {
      imgUrl = this.getAttribute("img");
    } else {
      imgUrl = "img/default.png";
    }

    const img = document.createElement("img");
    img.src = imgUrl;
    icon.appendChild(img);

    //  CSS  DOM 
    const style = document.createElement("style");
    console.log(style.isConnected);

    style.textContent = `
      .wrapper {
        position: relative;
      }

      .info {
        font-size: 0.8rem;
        width: 200px;
        display: inline-block;
        border: 1px solid black;
        padding: 10px;
        background: white;
        border-radius: 10px;
        opacity: 0;
        transition: 0.6s all;
        position: absolute;
        bottom: 20px;
        left: 10px;
        z-index: 3;
      }

      img {
        width: 1.2rem;
      }

      .icon:hover + .info, .icon:focus + .info {
        opacity: 1;
      }
    `;

    //  DOM 
    shadow.appendChild(style);
    console.log(style.isConnected);
    shadow.appendChild(wrapper);
    wrapper.appendChild(icon);
    wrapper.appendChild(info);
  }
}

(constructor()) super()

connectedCallback() DOM DOM CSS DOM

CustomElementRegistry define()

js
customElements.define("popup-info", PopupInfo);

HTML

html
<popup-info
  img="img/alt.png"
  data-text="Your card validation code (CVC)
  is an extra security feature  it is the last 3 or 4 numbers on the
  back of your card."></popup-info>

<style> DOM <link> <popup-info>

js
// 
class PopupInfo extends HTMLElement {
  constructor() {
    //  super 
    super();
  }

  connectedCallback() {
    // 
    const shadow = this.attachShadow({ mode: "open" });

    // span 
    const wrapper = document.createElement("span");
    wrapper.setAttribute("class", "wrapper");

    const icon = document.createElement("span");
    icon.setAttribute("class", "icon");
    icon.setAttribute("tabindex", 0);

    const info = document.createElement("span");
    info.setAttribute("class", "info");

    //  span 
    const text = this.getAttribute("data-text");
    info.textContent = text;

    // 
    let imgUrl;
    if (this.hasAttribute("img")) {
      imgUrl = this.getAttribute("img");
    } else {
      imgUrl = "img/default.png";
    }

    const img = document.createElement("img");
    img.src = imgUrl;
    icon.appendChild(img);

    //  DOM 
    const linkElem = document.createElement("link");
    linkElem.setAttribute("rel", "stylesheet");
    linkElem.setAttribute("href", "style.css");

    //  DOM 
    shadow.appendChild(linkElem);
    shadow.appendChild(wrapper);
    wrapper.appendChild(icon);
    wrapper.appendChild(info);
  }
}

<popup-info> DOM <link>

<link> (FOUC)

<style>

1 <ul>

: is

js
// 
class ExpandingList extends HTMLUListElement {
  constructor() {
    //  super 
    // super() 
    self = super();
  }

  connectedCallback() {
    //  ul  ul  li 
    // li  ul 
    const uls = Array.from(self.querySelectorAll("ul"));
    const lis = Array.from(self.querySelectorAll("li"));
    //  ul 
    // 
    uls.forEach((ul) => {
      ul.style.display = "none";
    });

    // ulli
    lis.forEach((li) => {
      //  li  ul 
      if (li.querySelectorAll("ul").length > 0) {
        // 
        // 
        li.setAttribute("class", "closed");

        // li  span 
        // span 
        const childText = li.childNodes[0];
        const newSpan = document.createElement("span");

        // li  span 
        newSpan.textContent = childText.textContent;
        newSpan.style.cursor = "pointer";

        //  span 
        newSpan.addEventListener("click", (e) => {
          // span  ul 
          const nextUl = e.target.nextElementSibling;

          // ul  class 
          if (nextUl.style.display === "block") {
            nextUl.style.display = "none";
            nextUl.parentNode.setAttribute("class", "closed");
          } else {
            nextUl.style.display = "block";
            nextUl.parentNode.setAttribute("class", "open");
          }
        });
        // span li 
        childText.parentNode.insertBefore(newSpan, childText);
        childText.parentNode.removeChild(childText);
      }
    });
  }
}

HTMLElement HTMLUListElement

connectedCallback()

define() options

js
customElements.define("expanding-list", ExpandingList, { extends: "ul" });

html
<ul is="expanding-list">
  
</ul>

<ul> is

DOM connectedCallback() DOM querySelectorAll() defer

html
<script src="main.js" defer></script>

connectedCallback() 1 <custom-square> <custom-square> 2 "size" "color"

DOM <div> <style>

js
class Square extends HTMLElement {
  // 
  constructor() {
    //  super 
    super();

    const shadow = this.attachShadow({ mode: "open" });

    const div = document.createElement("div");
    const style = document.createElement("style");
    shadow.appendChild(style);
    shadow.appendChild(div);
  }
  // 
}

updateStyle() <style> width, height, background-color

js
function updateStyle(elem) {
  const shadow = elem.shadowRoot;
  shadow.querySelector("style").textContent = `
    div {
      width: ${elem.getAttribute("size")}px;
      height: ${elem.getAttribute("size")}px;
      background-color: ${elem.getAttribute("color")};
    }
  `;
}

connectedCallback() DOM updateStyle()

js
class Square extends HTMLElement {
  // 
  connectedCallback() {
    console.log("");
    updateStyle(this);
  }
  // 
}

disconnectedCallback() adoptedCallback() DOM

js
class Square extends HTMLElement {
  // 
  disconnectedCallback() {
    console.log("");
  }

  adoptedCallback() {
    console.log("");
  }
  // 
}

attributeChangedCallback() 1 updateStyle()

js
class Square extends HTMLElement {
  // 
  attributeChangedCallback(name, oldValue, newValue) {
    console.log("");
    updateStyle(this);
  }
  // 
}

attributeChangedCallback() static get observedAttributes()

js
class Square extends HTMLElement {
  // 
  static get observedAttributes() {
    return ["color", "size"];
  }
  // 
}

Web Proxy Viewer  |  New URL  |  Original Page