2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

繰り返し利用可能なドロワーをjQueryライブラリを使わずにJavascriptで書く

Last updated at Posted at 2021-01-16

See the Pen 繰り返し利用可能なドロワーをJavaScriptだけで書く by 熊瀬川直也 (@momonoki1990) on CodePen.

使い方

  • ドロワーの開閉ボタンに data-drawer-btn="true" data-drawer-target="{ドロワーのid}" をセットする
  • ドロワー本体に id class="drawer" data-drawer="true" をセットする。
  • ドロワーを閉じるボタンに class="drawer" data-drawer-close-btn="true" data-drawer-target="{ドロワーのid}" をセットする
  • フェードレイヤーとナビゲーション(nav)が同じスタッキングコンテキストに属するように注意(ボタンの並びにおいて、共通の親要素であるdiv.my-drawer1がヘッダー、かつ、position:fixedでスタッキングコンテキストを生成してしまっていた時、フェードレイヤーがヘッダーの上か下になってしまい、結果としてヘッダーに内包されているナビゲーションも同じようにフェードレイヤの下か上になってしまって、ナビゲーションとヘッダーの間にフェードレイヤーを挟むことができず、嵌ってしまったので)

ベタがき

drawer.html
<div id="main">
  <div class="my-drawer1">
    <button class="drawer-btn" data-drawer-btn="true" data-drawer-target="drawer1">
      開閉ボタン1
    </button>
  </div>
  <nav class="drawer" id="drawer1" data-drawer="true">
      <div>
        <button class="drawer-close-btn" data-drawer-close-btn="true" data-drawer-target="drawer1">x</button>
      </div>
      <div class="drawer-menu">
        <div class="drawer-title">
          ドロワー1です
        </div>
      </div>
    </nav>
  <div class="my-drawer2">
    <button class="drawer-btn" data-drawer-btn="true" data-drawer-target="drawer2">
      開閉ボタン2
    </button>
  </div>
  <nav class="drawer" id="drawer2" data-drawer="true">
      <div>
        <button class="drawer-close-btn" data-drawer-close-btn="true" data-drawer-target="drawer2">x</button>
      </div>
      <div class="drawer-menu">
        <div class="drawer-title">
          ドロワー2です
        </div>
      </div>
    </nav>
  <div class="my-drawer3">
    <button class="drawer-btn" data-drawer-btn="true" data-drawer-target="drawer3">
      開閉ボタン3
    </button>
  </div>
  <nav class="drawer" id="drawer3" data-drawer="true">
      <div>
        <button class="drawer-close-btn" data-drawer-close-btn="true" data-drawer-target="drawer3">x</button>
      </div>
      <div class="drawer-menu">
        <div class="drawer-title">
          ドロワー3です
        </div>
      </div>
    </nav>
</div>

<style>
  .drawer {
    position: fixed;
    overflow: auto;
    top: 0;
    right: 0;
    padding: 1rem;
    background-color: red;
    width: 300px;
    height: 100%;
    z-index: 100;
    transition: all 0.2s;
    transform: translate(340px);
  }

  .drawer-open {
    transform: translate(0px);
  }

  .drawer-close-btn {
    position: absolute;
    top: 0;
    left: 0;
  }

  .fade-layer {
    position: absolute;
    top: 0px;
    left: 0px;

    width: 100%;
    height: 100%;

    background-color: #000000;
    opacity: 0.5;
    z-index: 99;
  }

  .d-none {
    display: none;
  }
</style>

<script type="text/javascript">

  // フェードレイヤーを生成しておく
  window.addEventListener('DOMContentLoaded', () => {
    const main = document.getElementById('main');
    const fadeLayer = document.createElement('div');
    fadeLayer.setAttribute('id', 'fade-layer');
    fadeLayer.classList.add('fade-layer', 'd-none');
    main.prepend(fadeLayer);
  })



  // フェードレイヤーの表示・非表示切り替え
  toggleFadeLayer = () => {
    const fadeLayer = document.getElementById('fade-layer');
    fadeLayer.classList.toggle('d-none');
  }



  // ドロワーの表示・非表示切り替え
  const toggleDrawer = (event) => {
    const currentTarget = event.currentTarget;
    const drawerTarget = currentTarget.getAttribute('data-drawer-target');
    const drawer = document.getElementById(drawerTarget);
    drawer.classList.toggle('drawer-open');
  }
  


  // ドロワーの開閉ボタンにクリックイベントを仕込む
  const drawers = document.querySelectorAll('[data-drawer-btn="true"]');
  drawers.forEach((drawer) => {
    drawer.addEventListener("click", (event) => {
      toggleDrawer(event);
      toggleFadeLayer()
    })
  })



  // ドロワーを閉じるボタンにクリックイベントを仕込む
  const drawerCloseBtns = document.querySelectorAll('[data-drawer-close-btn="true"]');
  drawerCloseBtns.forEach(closeBtn => {
    closeBtn.addEventListener('click', (event) => {
      toggleDrawer(event);
      toggleFadeLayer();
    })
  })



  // フェードレイヤーにクリックイベントを仕込む
  // フェードレイヤーがクリックされたらドロワーを閉じて、フェードレイヤーを非表示にする
  window.addEventListener('DOMContentLoaded', () => {
    const fadeLayer = document.getElementById('fade-layer');
    fadeLayer.addEventListener('click', () => {
    const openingDrawer = document.getElementsByClassName('drawer-open')[0];
    openingDrawer.classList.remove('drawer-open');
    fadeLayer.classList.add('d-none');
    })
  })

</script>
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?