← 動的パーツギャラリーへ戻る

パーツ番号 03-09-10 ・ JavaScript使用

ハンドル付きドラッグドロワー

右端のつまみハンドルを指でつまんで引き出す感覚でドロワーを開閉でき、軽くクリックするだけでも開閉が切り替わります。タブレット向けWordPressサイトのナビに。

clickjsoverlay

プレビュー

ソースコード

HTML

<div class="d03-09-10-stage">
          <main class="d03-09-10-main"><p>ハンドルをドラッグ、<br>またはクリックして開閉</p></main>
          <nav class="d03-09-10-drawer">
            <a href="#" onclick="return false" class="active">ホーム</a>
            <a href="#" onclick="return false">お知らせ</a>
            <a href="#" onclick="return false">ライブラリ</a>
            <a href="#" onclick="return false">設定</a>
            <span class="d03-09-10-handle" role="button" aria-label="ドロワーの開閉ハンドル"><i></i><i></i><i></i></span>
          </nav>
        </div>

CSS

.prev.d03-09-10{padding:0;display:block}
        .d03-09-10-stage{position:relative;width:100%;height:100%;min-height:260px;overflow:hidden;background:#f8fafc}
        .d03-09-10-main{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:16px}
        .d03-09-10-main p{margin:0;font-size:12px;color:#94a3b8;text-align:center;line-height:1.6}
        .d03-09-10-drawer{position:absolute;top:0;left:0;bottom:0;width:178px;background:#fff;box-shadow:2px 0 14px rgba(0,0,0,.1);display:flex;flex-direction:column;padding:20px 16px;gap:4px;transform:translateX(-142px);transition:transform .3s ease;z-index:2}
        .d03-09-10-drawer.open{transform:translateX(0)}
        .d03-09-10-drawer.dragging{transition:none}
        .d03-09-10-drawer a{color:#1f2937;text-decoration:none;font-size:13px;font-weight:600;padding:9px 4px;border-bottom:1px solid #f1f5f9}
        .d03-09-10-drawer a.active{color:#2563eb}
        .d03-09-10-drawer a:hover{color:#2563eb}
        .d03-09-10-handle{position:absolute;top:50%;right:-22px;transform:translateY(-50%);width:22px;height:56px;background:#2563eb;border-radius:0 10px 10px 0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;cursor:grab;touch-action:none}
        .d03-09-10-handle i{width:3px;height:15px;background:rgba(255,255,255,.85);border-radius:2px;pointer-events:none}

JavaScript

(function(){
        var stage=document.querySelector('.d03-09-10-stage');
        if(!stage)return;
        var drawer=stage.querySelector('.d03-09-10-drawer');
        var handle=stage.querySelector('.d03-09-10-handle');
        var CLOSED=-142,OPEN=0;
        var startX=0,startTx=CLOSED,dragging=false,moved=false;

        function setTx(x){
          x=Math.max(CLOSED,Math.min(OPEN,x));
          drawer.style.transform='translateX('+x+'px)';
          return x;
        }

        handle.addEventListener('pointerdown',function(e){
          dragging=true;moved=false;
          startX=e.clientX;
          startTx=drawer.classList.contains('open')?OPEN:CLOSED;
          drawer.classList.add('dragging');
          try{handle.setPointerCapture(e.pointerId);}catch(err){}
        });
        handle.addEventListener('pointermove',function(e){
          if(!dragging)return;
          var dx=e.clientX-startX;
          if(Math.abs(dx)>4)moved=true;
          setTx(startTx+dx);
        });
        function endDrag(e){
          if(!dragging)return;
          dragging=false;
          drawer.classList.remove('dragging');
          drawer.style.transform='';
          if(!moved){
            drawer.classList.toggle('open');
            return;
          }
          var dx=e.clientX-startX;
          var finalTx=startTx+dx;
          if(finalTx>CLOSED*0.5){
            drawer.classList.add('open');
          }else{
            drawer.classList.remove('open');
          }
        }
        handle.addEventListener('pointerup',endDrag);
        handle.addEventListener('pointercancel',endDrag);
      })();

クラス名 .d03-09-10 は本ライブラリ内での識別用です。複数のパーツを同じページで使う場合は、重複しないよう名前を変更してください。