パーツ番号 11-10-05 ・ JavaScript使用
引っ張り角度連動アイコン回転
引っ張った距離に応じて矢印アイコンがリアルタイムに回転し、閾値を超えると「離して更新」に文言が切り替わるプルトゥリフレッシュ。WordPressのモバイル対応トップページで直感的な更新操作を提供します。
プレビュー
ソースコード
HTML
<div class="d11-10-05-wrap">
<div class="d11-10-05-frame">
<div class="d11-10-05-indicator" id="d1465Ind">
<svg class="d11-10-05-arrow" id="d1465Arrow" viewBox="0 0 24 24" width="18" height="18"><path d="M12 4v13m0 0l-5-5m5 5l5-5" stroke="#4f46e5" stroke-width="2.4" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>
<span class="d11-10-05-label" id="d1465Label">引っ張って更新</span>
</div>
<div class="d11-10-05-scroll" id="d1465Scroll">
<ul class="d11-10-05-list" id="d1465List">
<li>投稿: 今日のコーディネート紹介</li>
<li>投稿: おすすめカフェ巡りレポ</li>
<li>投稿: 週末DIYの記録</li>
<li>投稿: 旅先で見つけた雑貨</li>
<li>投稿: 手作りお菓子レシピ</li>
</ul>
</div>
</div>
<p class="d11-10-05-hint">▼ 引っ張り具合で矢印が回転</p>
</div>CSS
.prev.d11-10-05{align-items:flex-start;justify-content:flex-start}
.d11-10-05-wrap{width:100%}
.d11-10-05-frame{position:relative;height:196px;overflow:hidden;border-radius:12px;background:#f8f9fb;border:1px solid #eef0f3}
.d11-10-05-indicator{position:absolute;top:0;left:0;right:0;height:44px;display:flex;align-items:center;justify-content:center;gap:6px;opacity:0;z-index:1}
.d11-10-05-arrow{transition:transform .05s linear}
.d11-10-05-label{font-size:10.5px;color:#4f46e5;font-weight:700}
.d11-10-05-indicator.is-ready .d11-10-05-label{color:#7c3aed}
.d11-10-05-indicator.is-loading .d11-10-05-arrow{animation:d1465Spin .7s linear infinite}
@keyframes d1465Spin{to{transform:rotate(360deg)}}
.d11-10-05-scroll{position:relative;z-index:2;height:100%;overflow-y:auto;background:#f8f9fb}
.d11-10-05-list{list-style:none;margin:0;padding:8px;display:flex;flex-direction:column;gap:7px}
.d11-10-05-list li{background:#fff;border:1px solid #eef0f3;border-radius:8px;padding:9px 11px;font-size:11.5px;color:#374151}
.d11-10-05-hint{margin:8px 0 0;font-size:10.5px;color:#9ca3af;text-align:center}JavaScript
(function(){
var root=document.getElementById('item-11-10-05');
var scroll=root.querySelector('#d1465Scroll');
var list=root.querySelector('#d1465List');
var ind=root.querySelector('#d1465Ind');
var arrow=root.querySelector('#d1465Arrow');
var label=root.querySelector('#d1465Label');
var startY=0,curD=0,dragging=false,pulling=false,refreshing=false;
var MAX=64,THRESH=48;
function getY(e){return e.touches?e.touches[0].clientY:e.clientY;}
function setD(d){
curD=d;
list.style.transform='translateY('+d+'px)';
ind.style.opacity=String(Math.min(d/THRESH,1));
var ratio=Math.min(d/THRESH,1);
arrow.style.transform='rotate('+(ratio*180)+'deg)';
if(!refreshing){
if(ratio>=1){ind.classList.add('is-ready');label.textContent='離して更新';}
else{ind.classList.remove('is-ready');label.textContent='引っ張って更新';}
}
}
function start(e){
if(refreshing||scroll.scrollTop>0)return;
startY=getY(e);dragging=true;pulling=false;
}
function move(e){
if(!dragging||refreshing)return;
var dy=getY(e)-startY;
if(dy<=0)return;
pulling=true;
if(e.cancelable)e.preventDefault();
setD(Math.min(dy*0.5,MAX));
}
function end(){
if(!dragging)return;
dragging=false;
if(!pulling)return;
pulling=false;
if(curD>=THRESH)refresh();else reset();
}
function refresh(){
refreshing=true;
list.style.transition='transform .2s';
setD(THRESH);
ind.classList.add('is-loading');
label.textContent='更新中...';
setTimeout(function(){
ind.classList.remove('is-loading');
reset();
refreshing=false;
},900);
}
function reset(){
list.style.transition='transform .25s ease';
ind.classList.remove('is-ready');
label.textContent='引っ張って更新';
setD(0);
setTimeout(function(){list.style.transition='';},250);
}
scroll.addEventListener('touchstart',start,{passive:true});
scroll.addEventListener('touchmove',move,{passive:false});
scroll.addEventListener('touchend',end);
scroll.addEventListener('touchcancel',end);
scroll.addEventListener('mousedown',start);
scroll.addEventListener('mousemove',move);
window.addEventListener('mouseup',end);
})();クラス名 .d11-10-05 は本ライブラリ内での識別用です。複数のパーツを同じページで使う場合は、重複しないよう名前を変更してください。