Handlebars

Handlebars & Web Components

ポップアップ情報 widget - web components

参考URL:
 https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM

 引き続き Web Component で、カスタムタグ<popup-info>の作成


上記のソースコード

<!-- CVC_link.html -->

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="description" content="Bulma Handlebars" />
    <title>Bulma Project [Web Components]</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css"
    />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bulma-extensions@6.2.7/dist/css/bulma-extensions.min.css"
    />

    <script
      defer
      src="https://use.fontawesome.com/releases/v5.7.1/js/all.js"
    ></script>

    <script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>

    <script src="/src/js/shortBulma$$.js"></script>
    <!-- <script src="/src/js/shortHbs$$.js"></script> -->

    <!-- <script src="main_link.js" defer></script> -->

    <style></style>
  </head>

  <body>
    <section class="section">
      <div class="container">
        <div class="columns">
          <div class="column"></div>
          <div class="column is-10 mt-4">
            <article class="message is-primary pb-3">
              <div class="message-header subtitle">
                <p>ポップアップ情報 widget - web components</p>
              </div>
              <div class="message-body has-text-centered is-size-5">
                <span class="is-size-5"
                  >参考URL:<br>https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM</span
                >
              </div>
            </article>

            <div class="columns is-centered mt-5 has-background-white-bis">
              <div class="column is-8 py-6">
                <div class="box">
                  <main>
                    <form>
                      <div class="field">
                        <label class="label"
                          >CVC の入力
                          <popup-info
                            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>
                        </label>
                        <div class="control has-icons-left">
                          <input
                            class="input"
                            id="cvc"
                            type="text"
                            placeholder="numbers input"
                          />
                          <span class="icon is-small is-left">
                            <i class="fas fa-user"></i>
                          </span>
                        </div>
                      </div>

                      <div class="field">
                        <label class="label"
                          >CVC の入力
                          <popup-info
                            img="alt_danger.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>
                        </label>
                        <div class="control has-icons-left">
                          <input
                            class="input"
                            id="cvc2"
                            type="text"
                            placeholder="numbers input"
                          />
                          <span class="icon is-small is-left">
                            <i class="fas fa-user"></i>
                          </span>
                        </div>
                      </div>

                      <div class="field">
                        <label class="label"
                          >CVC の入力
                          <popup-info
                            img="alt_success.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>
                        </label>
                        <div class="control has-icons-left">
                          <input
                            class="input"
                            id="cvc3"
                            type="text"
                            placeholder="numbers input"
                          />
                          <span class="icon is-small is-left">
                            <i class="fas fa-user"></i>
                          </span>
                        </div>
                      </div>
                    </form>
                  </main>
                </div>
              </div>
            </div>

            <div class="box mt-2">
              <div class="box">
                <h2 class="is-size-4 has-background-white-ter p-2 km">
                   解説
                </h2>
                <div class="content">
                  <ul>
                    <li class="pt-1">
                      <dl>
                        <dt>
                          <strong
                            >$$oa_t(this.shadowRoot, 'twoot-post');</strong
                          >
                        </dt>
                        <dd class="py-2">
                          テンプレート#templateをコンパイルし、コンテキストvを適用して得られたHTMLコードを、要素#contentsのinnserHTMLプロパティに代入する。
                        </dd>
                        <dt>
                          <strong>$$oq(this.shadowRoot, 'img')</strong>
                        </dt>
                        <dd class="py-2">
                          オブジェクトthis.shadowRootから'img'要素を求める。
                        </dd>
                        <dt>
                          <strong>$$oe = (o, f, evNa = 'click') </strong>
                        </dt>
                        <dd class="py-2">
                          オブジェクトthis.shadowRootに、clickイベントリスナーf
                          を登録する。
                        </dd>
                        <dt>
                          <strong
                            >$$ocL(this.options, 'hidden', 'remove');</strong
                          >
                        </dt>
                        <dd class="py-2">
                          オブジェクトから'hidden'クラスを取り除く。
                        </dd>
                      </dl>
                    </li>
                  </ul>
                </div>
              </div>
            </div>
          </div>

          <div class="column"></div>
        </div>
      </div>
    </section>

    <script>
      class PopUpInfo extends HTMLElement {
        constructor() {
          super();

          // Create a shadow root
          const shadow = this.attachShadow({ mode: 'open' });

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

          const icon = document.createElement('span');
          icon.setAttribute('class', 'icon');
          icon.setAttribute('tabindex', 0); // Tabキーによるフォーカスの移動順序を指定する属性

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

          const img = document.createElement('img');
          img.src = `./img/${imgUrl}`;
          icon.appendChild(img);

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

          const text = this.getAttribute('data-text');
          info.textContent = text;

          switch (imgUrl) {
            case 'alt.png':
              info.style.backgroundColor = '#67cebf';
              break;
            case 'alt_danger.png':
              info.style.backgroundColor = '#fee';
              break;
            case 'alt_success.png':
              info.style.backgroundColor = '#efb';
              break;
            default:
              info.style.backgroundColor = 'white';
          }

          wrapper.appendChild(icon);
          wrapper.appendChild(info);

          // Apply external styles to the shadow dom
          const styleElm = document.createElement('style');
          styleElm.innerHTML = `
            .wrapper {
              position: relative;
            }

            .info {
              font-size: 0.8rem;
              width: 200px;
              display: inline-block;
              border: 1px solid black;
              padding: 10px;
              // background:   #fee;
              // background:  #efb;
              // background:  #67cebf;
              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: 0.9;
            }
            `;

          // Attach the created elements to the shadow dom
          shadow.appendChild(styleElm);
          shadow.appendChild(wrapper);
        }
      }

      // Define the new element
      customElements.define('popup-info', PopUpInfo);
    </script>
  </body>
</html>

 解説

  • BulmaでJavascriptを利用するために、このWebサイトでは
     shortBulma$$.js または shortBulma.js
    というライブラリを使います。
  • 使い方の例:<script src="/src/js/shortBulma$$.js"></script>
    headタグ内に挿入。但し、pathは状況によって変わります。
  • 例えば、notification$$.htmlとshortBulma$$.jsが同じフォルダにある時は
    <script src="./shortBulma$$.js"></script> または
    <script src="shortBulma$$.js"></script> となります。


  • $$bulmaMenu('#burger', '#nav-links');
    狭い画面で表示されるBulmaのburgerメニューをコントロールします。
    burgerアイコンとbodyにそれぞれイベントを設定して、
    • [burgerアイコン]のクリックでburgerメニューを開閉
    • [body]のクリックでburgerメニューを閉じます。
    $$codeS('#pre1')
    コードの全コピーを準備するため、コードをクリックしたときにそれを選択状態にします。

    [ポップアップ情報]
    利用させていただいたのは、MDNのUsing shadow DOMです。
    Using shadow DOM