Можно использовать и в мобильном приложении на cordova/phonegap
стили можно перенсти в style.css
Код |
---|
(function () { if (!('ontouchstart' in window)) return; // Только на тач-устройствах function initPullToRefresh() { var startY = null; var dist = 0; var threshold = 70; var maxDist = 150; var pulling = false; var refreshTriggered = false; var spinner = document.createElement('div'); spinner.style.position = 'fixed'; spinner.style.top = '0'; spinner.style.left = '0'; spinner.style.right = '0'; spinner.style.height = '50px'; //spinner.style.background = 'white'; spinner.style.display = 'flex'; spinner.style.justifyContent = 'center'; spinner.style.alignItems = 'center'; spinner.style.fontSize = '24px'; spinner.style.color = '#007aff'; spinner.style.transform = 'translateY(-50px)'; spinner.style.transition = 'transform 0.3s ease, opacity 0.3s ease'; spinner.style.zIndex = '9999'; spinner.style.opacity = '0'; spinner.innerHTML = ` <svg style="width:24px; height:24px; animation: spin 1s linear infinite;" viewBox="0 0 50 50" > <rect x="10" y="10" width="30" height="30" stroke="#007aff" stroke-width="5" fill="none" /> </svg> `; document.body.appendChild(spinner); var styleEl = document.createElement('style'); styleEl.innerHTML = ` @keyframes spin { 0% { transform: rotate(0deg);} 100% { transform: rotate(360deg);} } `; document.head.appendChild(styleEl); // Проверяем, что прокрутка body/doc вверху function canPullToRefresh() { // Совместимый вариант для любых браузеров: return (window.pageYOffset || document.documentElement.scrollTop) === 0; } function onTouchStart(e) { if (canPullToRefresh() && !refreshTriggered) { startY = e.touches[0].screenY; pulling = true; dist = 0; spinner.style.transition = 'none'; spinner.style.opacity = '1'; } } function onTouchMove(e) { if (!pulling) return; var currentY = e.touches[0].screenY; dist = currentY - startY; if (dist > 0) { e.preventDefault(); // Блокируем скролл вниз при протягивании var moveDist = Math.min(dist, maxDist); spinner.style.transform = 'translateY(' + (moveDist - 50) + 'px)'; if (moveDist > threshold) { spinner.style.color = '#007aff'; } else { spinner.style.color = '#999'; } } else { spinner.style.transform = 'translateY(-50px)'; spinner.style.opacity = '0'; pulling = false; } } function onTouchEnd(e) { if (!pulling) return; spinner.style.transition = 'transform 0.3s ease, opacity 0.3s ease'; if (dist > threshold) { refreshTriggered = true; spinner.style.transform = 'translateY(0px)'; spinner.style.opacity = '1'; window.location.reload(); } else { spinner.style.transform = 'translateY(-50px)'; spinner.style.opacity = '0'; } pulling = false; startY = null; dist = 0; } window.addEventListener('touchstart', onTouchStart, {passive: false}); window.addEventListener('touchmove', onTouchMove, {passive: false}); window.addEventListener('touchend', onTouchEnd); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initPullToRefresh); } else { initPullToRefresh(); } })(); |