AI摘要

这段代码实现了网页“返回顶部”按钮的功能。通过CSS设计按钮样式,包含进度条与箭头图标。利用JavaScript编写多个函数,如节流、更新进度、控制滚动监听等,实现平滑滚动效果,还适配触摸事件,为用户提供流畅交互体验 。

此内容由AI生成,仅用于文章内容的总结

图片1图片2图片3

大体思路:创建一个按钮元素来作为 “返回顶部” 的按钮,在按钮内部添加色块填充一个用于显示进度条,以及返回顶部的箭头 SVG 图标,再写一些丝滑动画函数,实现平滑滚动效果。
为了让 “返回顶部” 按钮真正发挥作用,我们需要使用 JavaScript 来实现交互功能。定义一个节流函数 throttle,用于控制 updateProgress 函数的调用频率,避免在滚动过程中频繁触发导致性能问题.
updateProgress函数用于计算滚动进度并更新进度条的高度,同时根据滚动距离来显示或隐藏按钮
startScrollListenerstopScrollListener 函数分别用于开始和停止监听滚动事件
topFunction 函数实现点击按钮时,页面平滑滚动到顶部的效果,通过缓动函数easeInOutCubic让滚动更加丝滑

<style>
   .xoxo_fn_totop.active {
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
    }

    @media (max-width: 1040px) {
       .xoxo_fn_totop {
            right: 30px;
            bottom: 36px;
        }
    }

   .xoxo_fn_totop {
        position: fixed;
        z-index: 15;
        bottom: 46px;
        right: 40px;
        text-decoration: none;
        width: 50px;
        height: 50px;
        border: 4px solid #000;
        border-radius: 20px;
        background-color: #fff;
        display: -webkit-flex;
        display: -moz-flex;
        display: -ms-flex;
        display: -o-flex;
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        -ms-align-items: center;
        -webkit-box-align: center;
        -webkit-align-items: center;
        -ms-flex-align: center;
        align-items: center;
        -webkit-box-pack: center;
        -webkit-justify-content: center;
        -ms-flex-pack: center;
        justify-content: center;
        cursor: pointer;
        -webkit-transform: translateY(120px);
        -ms-transform: translateY(120px);
        transform: translateY(120px);
    }

   .xoxo_fn_totop:after {
        content: "";
        position: absolute;
        top: 0;
        left: -4px;
        right: -4px;
        bottom: -10px;
        z-index: -1;
        border-radius: 0 0 25px 25px;
        border-bottom: 10px solid #000;
    }

   .xoxo_fn_totop svg {
        width: 20px;
        height: 20px;
        z-index: 2; /* 确保箭头图标的 z-index 高于进度条 */
    }

    /* 进度条的样式 */
   .progress_wrapper {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 100%;
        border-radius: 16px;
        overflow: hidden;
    }

   .progress {
        display: block;
        width: 100%;
        height: 0%;
        background-color: #f9d40d; 
        transition: height 0.5s ease-in-out; 
        z-index: 1; /* 调整进度条的 z-index,使其位于箭头图标下方 */
    }
</style>

    <button onclick="topFunction()" id="myBtn" class="xoxo_fn_totop" title="回顶部">
        <span class="progress_wrapper">
            <span class="progress" style="height: 0%;"></span>
        </span>
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px"
            y="0px" viewBox="0 0 557.97 1061" style="enable-background:new 0 0 557.97 1061;" xml:space="preserve"
            class="fn__svg replaced-svg">
            <path d="M557.97,554.2c0,4.13,0,8.26,0,12.39c-0.37,2.83-0.75,5.66-1.11,8.49c-2.47,19.12-10.14,35.74-23.81,49.46  c-1.02,1.02-2.42,1.87-3.79,2.31c-8.96,2.89-18.12,3.28-27.38,1.91c-13.68-2.03-26.18-7.3-38.1-14.08  c-21.62-12.31-40.29-28.39-57.82-45.86c-28.44-28.34-53.31-59.63-76.03-92.68c-0.61-0.89-1.29-1.73-2.3-3.08  c-0.1,1.2-0.17,1.63-0.17,2.06c0.03,32.31-0.98,64.6-3.29,96.83c-1.56,21.73-3.32,43.46-5.57,65.13  c-2.71,26.12-6.58,52.09-11.66,77.88c-6.4,32.52-15.07,64.34-28.3,94.82c-22.74,52.42-51.12,101.67-83.67,148.55  c-17.42,25.09-35.96,49.32-57.81,70.77c-14.1,13.84-28.57,27.36-48.82,31.92c-1.97,0-3.95,0-5.92,0c-3.98-1.33-7.87-2.73-10.95-5.86  c-5.86-5.95-8.47-13.2-8.88-21.34c-0.68-13.44,2.95-26.11,7.27-38.6c7.44-21.55,17.29-42.09,27.01-62.67  c14.89-31.52,29.92-62.97,43.1-95.26c17.4-42.65,30.2-86.59,37.18-132.14c3.19-20.81,5.97-41.71,8.22-62.64  c2.09-19.52,3.54-39.12,4.7-58.73c1.05-17.73,1.42-35.5,1.92-53.26c0.95-34.02,0.14-68.02-1.36-102c-0.16-3.52-0.46-7.03-0.7-10.54  c-1.06,0.87-1.57,1.78-2.04,2.72c-18.76,36.7-39.4,72.27-63.39,105.83c-13.17,18.43-27.28,36.08-44.08,51.41  c-9.45,8.62-19.55,16.34-31.6,21.09c-7.23,2.86-14.69,4.16-22.4,2.77c-13.71-2.47-20.98-11.51-24.1-24.42  c-1.07-4.42-1.54-8.97-2.29-13.47c0-4.49,0-8.98,0-13.46c0.18-0.86,0.42-1.72,0.53-2.59c1.04-8.27,1.79-16.58,3.14-24.79  c3.57-21.68,9.15-42.91,15.05-64.05c9.97-35.71,20.36-71.3,30.05-107.09c9.64-35.6,17.21-71.58,18.86-108.63  c1.27-28.54,0.95-57.05,0.09-85.58c-0.86-28.33-2.7-56.65-1.36-85.02c0.56-11.84,1.68-23.63,4.84-35.09  C75.99,20.25,84.24,5.72,102.87,0c1.8,0,3.59,0,5.39,0c5.02,1.57,10.2,2.77,15.04,4.79c10.07,4.19,19.11,10.23,27.92,16.58  c22.42,16.14,42.81,34.66,62.61,53.83c49.96,48.37,96.11,100.26,141.08,153.24c9.64,11.35,18.66,23.27,28.83,34.13  c38.53,41.13,74.39,84.4,106,131.1c19.59,28.93,37.26,58.96,50.61,91.35c7.53,18.28,13.53,37.01,16.13,56.7  C557.02,545.87,557.47,550.04,557.97,554.2z"></path>
        </svg>
    </button>
<script>
    let rafId;
    let lastCall = 0;

    function throttle(func, limit) {
        return function() {
            const now = new Date().getTime();
            if (now - lastCall < limit) {
                return;
            }
            lastCall = now;
            return func.apply(this, arguments);
        };
    }

    function updateProgress() {
        // 计算进度条高度
        const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
        const scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
        const progress = Math.floor((scrollTop / scrollHeight) * 100); // 使用 Math.floor 取整
        const progressBar = document.querySelector('.progress');
        progressBar.style.height = `${progress}%`;

        // 当网页向下滑动 20px 出现"返回顶部" 按钮
        if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
            document.getElementById("myBtn").classList.add('active');
        } else {
            document.getElementById("myBtn").classList.remove('active');
        }

        rafId = window.requestAnimationFrame(updateProgress);
    }

    function startScrollListener() {
        updateProgress();
    }

    function stopScrollListener() {
        window.cancelAnimationFrame(rafId);
    }

    // 点击按钮,返回顶部
    function topFunction() {
        const startY = window.scrollY || document.documentElement.scrollTop || document.body.scrollTop;
        const startTime = performance.now();
        const duration = 500; // 滚动持续时间,单位为毫秒,可根据需要调整

        function scrollToTop(currentTime) {
            const elapsed = currentTime - startTime;
            const progress = Math.min(elapsed / duration, 1);
            const ease = easeInOutCubic(progress); // 使用缓动函数
            const newY = startY * (1 - ease);

            document.body.scrollTop = newY;
            document.documentElement.scrollTop = newY;

            if (progress < 1) {
                window.requestAnimationFrame(scrollToTop);
            } else {
                stopScrollListener();
            }
        }

        window.requestAnimationFrame(scrollToTop);
    }

    // 缓动函数,这里使用的是 easeInOutCubic 函数,可以根据需要替换为其他缓动函数
    function easeInOutCubic(t) {
        return t < 0.5? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
    }

    // 使用 throttle 函数对 updateProgress 进行节流
    const throttledUpdateProgress = throttle(updateProgress, 10);

    // 开始监听滚动事件
    window.addEventListener('scroll', throttledUpdateProgress);

    // 监听触摸事件,使在触摸设备上也能正常工作
    document.addEventListener('touchstart', function (e) {
        startScrollListener();
    });
    document.addEventListener('touchmove', function (e) {
        throttledUpdateProgress();
    });
    document.addEventListener('touchend', function (e) {
        stopScrollListener();
    });
</script>


通过以上代码,我们就成功地实现了一个丝滑的网页返回顶部样式,它不仅在视觉上有吸引力,而且在交互上也非常流畅,能够为用户带来良好的浏览体验。你可以根据自己的喜好进一步调整样式和功能,让它更好地融入你的网页设计中。

编写不易,转载务必保留原文链接!