Greasy Fork

来自缓存

Greasy Fork is available in English.

页面下拉刷新 1.30

页面顶部下拉展示动画,包含刷新功能。改进自原代码作者:路灯下的豆子不结籽

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name    页面下拉刷新 1.30
// @namespace    https://example.com
// @version    1.30
// @description 页面顶部下拉展示动画,包含刷新功能。改进自原代码作者:路灯下的豆子不结籽
// @match    *://*/*
// @exclude http://greasyfork.icu/*
// @grant    none
// @license MIT
// ==/UserScript==
(function () {
    'use strict';
    // 设置下拉的比例,这里设为 10%
    const pullDownRatio = 0.1; 
    // 用于记录触摸开始时手指在 Y 轴上的坐标
    let startY = 0; 
    // 标记是否处于触摸拖动状态,初始为 false
    let isDragging = false; 
    // 设置下挪和回弹动画的持续时间,单位为秒,固定为 0.3 秒
    const animationDuration = 0.3; 
    // 设置动画的缓动函数,这里使用 'ease' 使动画更自然平滑
    const easeFunction = 'ease'; 
    // 用于记录当前下拉的距离
    let currentDistance = 0;

    // 获取页面的 body 元素,后续用于操作页面的位移来实现动画效果
    const body = document.querySelector('body'); 

    // 计算下拉的阈值(基于页面高度的比例)
    const threshold = window.innerHeight * pullDownRatio; 

    // 开始下拉动画的函数
    function startPullDownAnimation() {
        // 明确设置 transform 的初始值为 translateY(0),确保动画起始状态正确
        body.style.transform = 'translateY(0)';
        // 设置页面 body 的过渡动画属性,包括持续时间和缓动函数
        body.style.transition = `transform ${animationDuration}s ${easeFunction}`; 
        // 将页面 body 向下平移计算出的阈值距离,实现下拉动画效果
        body.style.transform = `translateY(${threshold}px)`; 
    }

    // 开始回弹动画的函数
    function startReboundAnimation() {
        // 明确设置 transform 的目标值为 translateY(0),确保动画结束状态正确
        body.style.transform = `translateY(${threshold}px)`;
        // 设置页面 body 的过渡动画属性,包括持续时间和缓动函数
        body.style.transition = `transform ${animationDuration}s ${easeFunction}`; 
        // 将页面 body 移回初始位置(Y 轴位移为 0),实现回弹动画效果
        body.style.transform = 'translateY(0)'; 
    }

    // 监听触摸开始事件
    document.addEventListener('touchstart', function (e) {
        // 判断页面是否在最顶部(滚动条 Y 轴位置为 0)
        if (window.scrollY === 0) {
            // 记录触摸开始时手指的 Y 坐标
            startY = e.touches[0].clientY; 
            // 标记进入触摸拖动状态
            isDragging = true; 
            // 开始拖动时取消过渡动画,使拖动操作更流畅
            body.style.transition = 'none'; 
            // 在控制台打印日志,显示触摸开始时记录的 Y 坐标
            console.log('touchstart: startY set to', startY); 
        }
    });

    // 监听触摸移动事件
    document.addEventListener('touchmove', function (e) {
        // 判断页面是否在最顶部(滚动条 Y 轴位置为 0)
        if (window.scrollY === 0 && isDragging) {
            // 获取当前触摸点的 Y 坐标
            const currentY = e.touches[0].clientY; 
            // 计算触摸点移动的距离
            currentDistance = currentY - startY; 

            // 如果移动距离大于 0,则直接控制页面的位移
            if (currentDistance > 0) {
                // 直接设置页面的位移
                body.style.transform = `translateY(${currentDistance}px)`;
            }

            // 当移动距离超过阈值时,直接触发回弹动画
            if (currentDistance > threshold) {
                startReboundAnimation();
                // 监听回弹动画结束事件,在动画结束后刷新页面
                body.addEventListener('transitionend', function onTransitionEnd() {
                    // 移除事件监听器,避免重复执行
                    body.removeEventListener('transitionend', onTransitionEnd);
                    // 执行页面刷新
                    console.log('Reloading page...');
                    location.reload();
                }, { once: true });
                // 重置拖动状态
                isDragging = false;
                // 重置当前下拉距离
                currentDistance = 0;
            }
        }
    });

    // 监听触摸结束事件
    document.addEventListener('touchend', function () {
        if (isDragging) {
            // 如果下拉距离超过阈值,触发回弹动画
            if (currentDistance > threshold) {
                startReboundAnimation();
                // 监听回弹动画结束事件,在动画结束后刷新页面
                body.addEventListener('transitionend', function onTransitionEnd() {
                    // 移除事件监听器,避免重复执行
                    body.removeEventListener('transitionend', onTransitionEnd);
                    // 执行页面刷新
                    console.log('Reloading page...');
                    location.reload();
                }, { once: true });
            } else {
                // 如果下拉距离未超过阈值,也执行回弹动画使页面回到初始位置
                startReboundAnimation();
            }
        }
        // 重置触摸开始时记录的 Y 坐标为 0
        startY = 0; 
        // 重置拖动状态
        isDragging = false;
        // 重置当前下拉距离
        currentDistance = 0;
    });

    // 监听触摸取消事件
    document.addEventListener('touchcancel', function () {
        if (isDragging) {
            // 执行回弹动画函数,使页面回到初始位置
            startReboundAnimation();
            // 监听回弹动画结束事件,在动画结束后刷新页面
            body.addEventListener('transitionend', function onTransitionEnd() {
                // 移除事件监听器,避免重复执行
                body.removeEventListener('transitionend', onTransitionEnd);
                // 执行页面刷新
                console.log('Reloading page...');
                location.reload();
            }, { once: true });
            // 重置触摸开始时记录的 Y 坐标为 0
            startY = 0; 
            // 重置拖动状态
            isDragging = false;
            // 重置当前下拉距离
            currentDistance = 0;
        }
    });
})();