Skip to content

create native custom elements with vanilla javascript - step by step example

Notifications You must be signed in to change notification settings

edsaio/getting-started-custom-elements

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 

Repository files navigation

getting-started-custom-elements

create native custom elements with vanilla javascript - step by step example

alt text

Steps

  • Create html

      <!doctype html>
      <html>
        <head>
          <base href="/">
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
          <title>Getting Started with Custom Elements</title>
        </head>
        <body>
          <star-rating></star-rating>
          <script>
            /// add your javascript here
          </script>
        </body>
      </html>
  • Defining an element

    class StartRatingElement extends HTMLElement {
    
      constructor() {
        super();
      }
    
    }
    
    // * Rules on creating custom elements
    //  * The name of a custom element must contain a dash (-). 
    //     This requirement is so the HTML parser can distinguish 
    //     custom elements from regular elements.
    //  * You can't register the same tag more than once.
    //  * Always write a closing tag (<star-rating></star-rating>).
    customElements.define('star-rating', StartRatingElement);
  • Adding Properties and Attibutes

    class StartRatingElement extends HTMLElement {
    
      constructor() {
        super();
      }
    
      /// list of attribute expose to the browser
      /// ie. <star-rating checked></star-rating>
      static get observedAttributes() {
        return [ 'checked' ];
      }
    
      /// called when attribute change from the dom
      /// check if custom element has checked attribute
      /// i.e <star-rating checked></star-rating>
      ///   since <star-rating> element has attribute it will return true;
      get checked() {
        return this.hasAttribute('checked');
      }
    
      /// call when attribute change from the dom
      set checked(value) {
        /// find the span element then add or remove a class to span
        /// if the value === true, it will add 'checked' class to the span element
        ///   i.e <span class="checked"></span>
        const span = this.querySelector('span');
        if (value) {
          span.classList.add('checked');
        } else {
          span.classList.remove('checked');
        }
      }
    
      /// called when an observed attribute has been added, removed, updated, or replaced. 
      //  Note: only attributes listed in the observedAttributes property will receive this callback.
      attributeChangedCallback(name, oldValue, newValue) {
        switch(name) {
          case 'checked':
            this.checked = this.checked;
            break;
        }
      }
    
    }
  • Add markup and style

      class StartRatingElement extends HTMLElement {
    
        constructor() {
          super();
        }
    
        /// list of attribute expose to the browser
        /// ie. <star-rating checked></star-rating>
        static get observedAttributes() {
          return [ 'checked' ];
        }
    
        /// call or execute of attribute change from the dom
        /// check if custom element has checked attribute
        /// i.e <star-rating checked></star-rating>
        ///   since <star-rating> element has attribute it will return true;
        get checked() {
          return this.hasAttribute('checked');
        }
    
        /// call or execute of attribute change from the dom
        set checked(value) {
          /// find the span element then add or remove a class to span
          /// if the value = true, it will add 'checked' class to the span element
          ///   i.e <span class="checked"></span>
          const span = this.querySelector('span');
          if (value) {
            span.classList.add('checked');
          } else {
            span.classList.remove('checked');
          }
        }
    
        /// called when an observed attribute has been added, removed, updated, or replaced. 
        //  Note: only attributes listed in the observedAttributes property will receive this callback.
        attributeChangedCallback(name, oldValue, newValue) {
          switch(name) {
            case 'checked':
              this.checked = this.checked;
              break;
          }
        }
    
        /// called every time the element is inserted into the DOM. 
        /// useful for running setup code, such as fetching resources or rendering.
        connectedCallback() {
          const template = document.createElement('template');
          template.innerHTML = `
            <style>
              .checked svg {
                fill: orange;
              }
              span svg {
                width: 2%;
              }
            </style>
            <span>
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
                <path d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"/>
              </svg>
            </span>
          `;
          /// this will add the element to the dom
          this.appendChild(template.content);
        }
      }
  • Adding event

      class StartRatingElement extends HTMLElement {
    
        constructor() {
          super();
        }
    
        /// list of attribute expose to the browser
        /// ie. <star-rating checked></star-rating>
        static get observedAttributes() {
          return [ 'checked' ];
        }
    
        /// call or execute of attribute change from the dom
        /// check if custom element has checked attribute
        /// i.e <star-rating checked></star-rating>
        ///   since <star-rating> element has attribute it will return true;
        get checked() {
          return this.hasAttribute('checked');
        }
    
        /// call or execute of attribute change from the dom
        set checked(value) {
          /// find the span element then add or remove a class to span
          /// if the value = true, it will add 'checked' class to the span element
          ///   i.e <span class="checked"></span>
          const span = this.querySelector('span');
          if (value) {
            span.classList.add('checked');
          } else {
            span.classList.remove('checked');
          }
        }
    
        /// called when an observed attribute has been added, removed, updated, or replaced. 
        //  Note: only attributes listed in the observedAttributes property will receive this callback.
        attributeChangedCallback(name, oldValue, newValue) {
          switch(name) {
            case 'checked':
              this.checked = this.checked;
              break;
          }
        }
    
        /// called every time the element is inserted into the DOM. 
        /// useful for running setup code, such as fetching resources or rendering.
        connectedCallback() {
          const template = document.createElement('template');
          template.innerHTML = `
            <style>
              .checked svg {
                fill: orange;
              }
              span svg {
                width: 2%;
              }
            </style>
            <span>
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
                <path d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"/>
              </svg>
            </span>
          `;
          /// this will add the element to the dom
          this.appendChild(template.content);
    
          /// add click event to the element
          this.addEventListener('click', function(e) {
            if (this.checked) {
              this.removeAttribute('checked');
            } else {
              this.setAttribute('checked', '')
            }
          })
        }
    
      }

Releases

No releases published

Packages

No packages published

Languages