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

パーツ番号 08-08-10 ・ JavaScript使用

慣性スクロールリスト

ドラッグの勢いのままリストが滑らかに減速しながらスクロールする慣性付きリストです。WordPressのモバイル向けメニューやランキング一覧に使えます。

mobilescrolldragjs

プレビュー

ソースコード

HTML

<div class="d08-08-10-wrap">
          <ul class="d08-08-10-list">
            <li>アイテム 01</li><li>アイテム 02</li><li>アイテム 03</li><li>アイテム 04</li>
            <li>アイテム 05</li><li>アイテム 06</li><li>アイテム 07</li><li>アイテム 08</li>
          </ul>
        </div>

CSS

.d08-08-10-wrap{width:100%;max-width:220px;height:200px;overflow:hidden;border-radius:14px;border:1px solid #eef0f3;position:relative;background:#fff}
        .d08-08-10-list{list-style:none;margin:0;padding:0;will-change:transform;touch-action:none;cursor:grab}
        .d08-08-10-list li{padding:14px 16px;font-size:13px;font-weight:600;color:#3a3d4a;border-bottom:1px solid #f1f2f6;user-select:none}

JavaScript

(function(){
        var root=document.querySelector('#item-08-08-10 .d08-08-10');
        var wrap=root&&root.querySelector('.d08-08-10-wrap');
        var list=root&&root.querySelector('.d08-08-10-list');
        if(!list||!wrap)return;
        var y=0,minY=0,startY=0,lastY=0,lastT=0,vy=0,dragging=false,raf=null;
        function getY(e){return e.touches&&e.touches.length?e.touches[0].clientY:e.clientY;}
        function bounds(){minY=Math.min(0,wrap.clientHeight-list.scrollHeight);}
        function apply(ny){
          bounds();
          ny=Math.max(minY,Math.min(0,ny));
          y=ny;
          list.style.transform='translateY('+y+'px)';
        }
        function onDown(e){
          dragging=true;
          if(raf)cancelAnimationFrame(raf);
          list.style.transition='none';
          startY=getY(e);lastY=startY;lastT=Date.now();vy=0;
          document.addEventListener('mousemove',onMove);
          document.addEventListener('mouseup',onUp);
        }
        function onMove(e){
          if(!dragging)return;
          if(e.cancelable)e.preventDefault();
          var cy=getY(e);
          var dy=cy-lastY;
          var now=Date.now();
          var dt=Math.max(1,now-lastT);
          vy=dy/dt;
          apply(y+dy);
          lastY=cy;lastT=now;
        }
        function onUp(){
          if(!dragging)return;
          dragging=false;
          document.removeEventListener('mousemove',onMove);
          document.removeEventListener('mouseup',onUp);
          var v=vy*16;
          function step(){
            v*=0.94;
            if(Math.abs(v)<0.4)return;
            apply(y+v);
            if(y<=minY||y>=0){v=0;return;}
            raf=requestAnimationFrame(step);
          }
          raf=requestAnimationFrame(step);
        }
        list.addEventListener('mousedown',onDown);
        list.addEventListener('touchstart',onDown,{passive:true});
        list.addEventListener('touchmove',onMove,{passive:false});
        list.addEventListener('touchend',onUp);
        bounds();
      })();

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