Typecho 文档:给文章页添加无感翻上下篇功能

03月08日

适用程序:Typecho
程序版本:1.2.1
文档作者:Lopwon
作者博客:Lopwon.com
发布页面:Lopwon.com/attachment/3950/
许可方式:CC BY-NC-SA
官方演示:前往

注意:此文档源于作者在博客改造中的一些经验总结,转载还请署名。

敬告:此文档操作涉及程序核心文件的修改,作者不对你在使用中产生的任何问题造成的不良后果,承担责任。

文档说明

在 APP 内,可以通过手势操作上下滑动页面达到翻页浏览内容的目的,而在博客中,文章的上一篇下一篇需要点击链接才能打开对应页面,本文档尝试让博客文章也能滚动翻篇,实现类似 APP 的翻页效果。


使用方法

A 涉及文件

usr/themes/***/post.php

B 改造文件

作用:给文章页实现懒人翻篇功能

1. 打开文件 post.php 在翻篇代码 $this->theNext 和 $this->thePrev 外层添加容器 id="theNext " 和 id="thePrev",如:

    <span id="theNext "><?php $this->theNext ('%s', '没有了'); ?></span>

    <span id="thePrev"><?php $this->thePrev('%s', '没有了'); ?></span>

以上操作主要是为了让 JavaScript 能够获取翻篇链接。

2. 继续在文件 post.php 引入以下代码:

    <script>
    window.onload = function() {
        const hasNext = document.getElementById('theNext'); // 翻篇 id="theNext" 元素
        const hasPrev = document.getElementById('thePrev'); // 翻篇 id="thePrev" 元素
    
        // 如果页面缺少两个翻篇 id 元素,则弹出提示并退出执行
        if (!hasNext && !hasPrev) {
            alert('页面中缺少翻篇 id="theNext" 和 id="thePrev" 元素,请先添加!');
            return;
        }
    
        window.scrollTo(0, 15); // 设置页面初始滚动位置为 15px 避免 scrollTop === 0 时,无法上滚页面触发向上翻篇
    
        let timeout; // 定义变量用于存储防抖定时器
        let isInitialLoad = true; // 定义标志变量,标记页面是否为初次加载  
    
        const nextLink = hasNext && hasNext.querySelector('a')?.href; // 获取 theNext 链接
        const prevLink = hasPrev && hasPrev.querySelector('a')?.href;  // 获取 thePrev 链接
    
        window.addEventListener('scroll', function() { // 监听滚动
            clearTimeout(timeout); // 清除之前的防抖定时器,避免重复触发
    
            timeout = setTimeout(function() { // 设置新的防抖定时器 200ms 后执行滚动逻辑
                const scrollTop = window.pageYOffset || document.documentElement.scrollTop; // 获取当前滚动条距离顶部的距离(兼容不同浏览器)
                const scrollHeight = document.documentElement.scrollHeight; // 获取文档的总高度
                const clientHeight = document.documentElement.clientHeight; // 获取浏览器视口的高度
    
                if (scrollTop <= 5 && !isInitialLoad && nextLink) { // 判断是否滚动到顶部,且不是初次加载,且 nextLink 存在
                    window.location.href = nextLink; // 执行页面跳转到 nextLink
                } else if (scrollTop + clientHeight >= scrollHeight && prevLink) { // 判断是否滚动到底部,且 prevLink 存在
                    window.location.href = prevLink; // 执行页面跳转到 prevLink
                }
            }, 200); // 防抖延迟时间,避免频繁触发
    
            if (isInitialLoad) { // 如果是初次加载
                isInitialLoad = false; // 将 isInitialLoad 置为 false 避免加载时立即跳转
            }
        });
    };
    </script>

至此,将滚动条触顶时,则自动向上翻篇,将滚动条触底时,则自动向下翻篇,无需点击翻篇链接。当然,以上只是功能实现,也可以在此基础上做优化,让交互更友好,比如,在即将触底时,提示用户是否自动执行翻篇,等等。

需要注意的是,当页面中使用了返回顶部的功能时,请将返回顶部的值预留 15px 以避免为 0px 时直接触发翻篇。

以上无感翻上下篇的功能过于灵敏,即只要滚动条触顶或触底时,会立即执行翻篇,体验感略差。在作者 Lopwon 制作的主题 Snapic Just640px 中除了使用相同功能外,还对灵敏度做了可自定义的优化,即在滚动条触顶或触底时,给出缓冲过渡的阀值,以增强体验感。

Snapic Plus v5 Lopwon Hub