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

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

スワイプで既読・削除リスト

メールアプリのようにカードを左右にドラッグすると、既読化や削除アクションが下から現れます。WordPressの通知一覧やお知らせ管理画面のUIに応用できます。

dragjs

プレビュー

ソースコード

HTML

<ul class="d08-08-02-list">
          <li class="d08-08-02-row">
            <div class="d08-08-02-actions">
              <span class="d08-08-02-act d08-08-02-read">既読</span>
              <span class="d08-08-02-act d08-08-02-del">削除</span>
            </div>
            <div class="d08-08-02-card"><b>田中様より</b><p>お見積りの件でご連絡しました</p></div>
          </li>
          <li class="d08-08-02-row">
            <div class="d08-08-02-actions">
              <span class="d08-08-02-act d08-08-02-read">既読</span>
              <span class="d08-08-02-act d08-08-02-del">削除</span>
            </div>
            <div class="d08-08-02-card"><b>山田様より</b><p>打合せ日程のご確認です</p></div>
          </li>
        </ul>

CSS

.d08-08-02-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px;width:100%;max-width:260px}
        .d08-08-02-row{position:relative;overflow:hidden;border-radius:12px}
        .d08-08-02-actions{position:absolute;inset:0;display:flex}
        .d08-08-02-act{flex:1;display:flex;align-items:center;color:#fff;font-size:11.5px;font-weight:700}
        .d08-08-02-read{background:#3b82f6;justify-content:flex-start;padding-left:16px}
        .d08-08-02-del{background:#ef4444;justify-content:flex-end;padding-right:16px}
        .d08-08-02-card{position:relative;background:#fff;border:1px solid #eef0f3;border-radius:12px;padding:10px 14px;touch-action:pan-y;cursor:grab}
        .d08-08-02-card b{font-size:12.5px}
        .d08-08-02-card p{font-size:11.5px;color:#8a8f9c;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
        .d08-08-02-row.is-read .d08-08-02-card b{color:#9aa0ad}

JavaScript

(function(){
        var root=document.querySelector('#item-08-08-02 .d08-08-02');
        var rows=root?root.querySelectorAll('.d08-08-02-row'):[];
        function getX(e){return e.touches&&e.touches.length?e.touches[0].clientX:e.clientX;}
        rows.forEach(function(row){
          var card=row.querySelector('.d08-08-02-card');
          var startX=0,dx=0,dragging=false;
          function onDown(e){
            dragging=true;startX=getX(e);card.style.transition='none';
            document.addEventListener('mousemove',onMove);
            document.addEventListener('mouseup',onUp);
          }
          function onMove(e){
            if(!dragging)return;
            if(e.cancelable)e.preventDefault();
            dx=getX(e)-startX;
            dx=Math.max(-110,Math.min(110,dx));
            card.style.transform='translateX('+dx+'px)';
          }
          function onUp(){
            if(!dragging)return;
            dragging=false;
            document.removeEventListener('mousemove',onMove);
            document.removeEventListener('mouseup',onUp);
            card.style.transition='transform .28s cubic-bezier(.2,.8,.2,1)';
            if(dx<-60){
              card.style.transform='translateX(-100%)';
              card.style.opacity='0';
              setTimeout(function(){
                card.style.transition='none';
                card.style.transform='translateX(0)';
                card.style.opacity='1';
              },650);
            }else if(dx>60){
              card.style.transform='translateX(0)';
              row.classList.add('is-read');
            }else{
              card.style.transform='translateX(0)';
            }
            dx=0;
          }
          card.addEventListener('mousedown',onDown);
          card.addEventListener('touchstart',onDown,{passive:true});
          card.addEventListener('touchmove',onMove,{passive:false});
          card.addEventListener('touchend',onUp);
          card.addEventListener('click',function(){row.classList.add('is-read');});
        });
      })();

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