JS 求助,在右上角添加「PgUp PgDn 」上下翻页按钮

如题,添加 2 个翻页按钮
  1. 按钮图标用 ↑ ↓ 这 2 个箭头
  2. 可以隐藏箭头,上翻页 很难用得上,默认隐藏上翻页 按钮
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    28446 引用 • 119768 回帖
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    11155 引用 • 50651 回帖 • 52 关注
1 操作
8V9q7V 在 2025-10-09 23:26:59 更新了该帖

相关帖子

被采纳的回答
  • wilsons 1

    不知是否你想要的,有问题再告知

    // 右上角按钮实现上下翻新页
    // see https://ld246.com/article/1759977992135
    // vesion 0.0.3
    // 0.0.3 新增alt+点击下方向键 向下滚动指定行,alt+shift+点击下方向键,向上滚动指定行;向下按钮和alt+点击向下按钮滚动时,会保留一定的重叠区域,方便浏览时衔接
    // 0.0.2 修复滚动算法错误(之前的视窗计算有误差);增加ctrl+点击向下方向键,实现向上翻页功能
    (async ()=>{
        // 是否显示向上翻页按钮 true 显示 false 不显示
        const isShowPageUpBtn = false;
    
        // alt+点击 滚动高度,这里用行高 * 3 表示,由于每个人的行高不一样,这里可自行修改
        const altClickScrollHeight = 34 * 3;
        
        // 重叠高度,当上下滚动时,有一部分重叠区域不滚动(并非完全滚动整个视窗),方便上下文衔接,可根据自己需要修改
        const overlap = 40;
    
        // 不支持手机版
        if(isMobile()) return;
      
        // 添加toolbar按钮
        whenElementExist('#toolbar .fn__ellipsis').then((el)=>{
            if(!el) return;
            const pageDownBtnHtml = `<div data-menu="true" id="pageDownBtn" class="toolbar__item ariaLabel" aria-label="点击向下翻页" data-location="right"><svg style=""><use xlink:href="#iconArrowDown"></use></svg></div>`;
            el.insertAdjacentHTML('afterend', pageDownBtnHtml);
            const pageDownBtn = el.nextElementSibling;
            pageDownBtn.addEventListener('click', (event) => {
                const protyleEl = getProtyleEl();
                const scrollEl = protyleEl?.querySelector('.protyle-content');
                const isCtrlPressed = (event.ctrlKey || event.metaKey) && !event.shiftKey && !event.altKey;
                const isAltPressed = event.altKey && !event.shiftKey && !event.ctrlKey && !event.metaKey;
                const isAltShiftPressed = event.altKey && event.shiftKey && !event.ctrlKey && !event.metaKey;
                // ctrl+点击向下方向键按钮
                if(isCtrlPressed) scrollPage(scrollEl, true);
                // alt+点击向下方向键按钮
                else if(isAltPressed) scrollPage(scrollEl, false, altClickScrollHeight);
                // alt+shift+点击向下方向键按钮
                else if(isAltShiftPressed) scrollPage(scrollEl, true, altClickScrollHeight);
                // 直接点击向下方向键按钮
                else scrollPage(scrollEl, false);
                
            });
    
            if(isShowPageUpBtn) {
                const pageUpBtnHtml = `<div data-menu="true" id="pageUpBtn" class="toolbar__item ariaLabel" aria-label="点击向上翻页" data-location="right"><svg style="transform: scaleY(-1);"><use xlink:href="#iconArrowDown"></use></svg></div>`;
                el.insertAdjacentHTML('afterend', pageUpBtnHtml);
                const pageUpBtn = el.nextElementSibling;
                pageUpBtn.addEventListener('click', (event) => {
                    const protyleEl = getProtyleEl();
                    const scrollEl = protyleEl?.querySelector('.protyle-content');
                    scrollPage(scrollEl, true);
                });
            }
        });
    
        function scrollPage(element, isPageUp = true, amount = 0) {
          const scroller = element || window;
          const pageHeight = scroller === window 
            ? window.innerHeight 
            : scroller.clientHeight;
        
          const scrollOptions = { 
            top: isPageUp ? (amount?-amount:(-pageHeight+overlap)) : (amount?amount:(pageHeight-overlap)),
            // behavior: 'smooth' // 按需开启
          };
        
          if (scroller === window) {
            window.scrollBy(scrollOptions);
          } else {
            scroller.scrollBy(scrollOptions);
          }
        }
        function getProtyleEl() {
            return document.querySelector('#editor') || document.querySelector(`.protyle[data-id="${[...document.querySelectorAll('.layout-tab-bar [data-type="tab-header"]')]
              .reduce((max, tab) => Number(tab?.dataset?.activetime) > Number(max?.dataset?.activetime || -1) ? tab : max, null)?.dataset?.id}"]`);
        }
        function whenElementExist(selector, node = document, timeout = 5000) {
            return new Promise((resolve, reject) => {
                const start = Date.now();
                function check() {
                    let el;
                    try {
                        el = typeof selector === 'function'
                            ? selector()
                            : node.querySelector(selector);
                    } catch (err) {
                        return resolve(null);
                    }
                    if (el) {
                        resolve(el);
                    } else if (Date.now() - start >= timeout) {
                        resolve(null);
                    } else {
                        requestAnimationFrame(check);
                    }
                }
                check();
            });
        }
        function isMobile() {
            return !!document.getElementById("sidebar");
        }
    })();
    

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • wilsons 1 2 评论

    不知是否你想要的,有问题再告知

    // 右上角按钮实现上下翻新页
    // see https://ld246.com/article/1759977992135
    // vesion 0.0.3
    // 0.0.3 新增alt+点击下方向键 向下滚动指定行,alt+shift+点击下方向键,向上滚动指定行;向下按钮和alt+点击向下按钮滚动时,会保留一定的重叠区域,方便浏览时衔接
    // 0.0.2 修复滚动算法错误(之前的视窗计算有误差);增加ctrl+点击向下方向键,实现向上翻页功能
    (async ()=>{
        // 是否显示向上翻页按钮 true 显示 false 不显示
        const isShowPageUpBtn = false;
    
        // alt+点击 滚动高度,这里用行高 * 3 表示,由于每个人的行高不一样,这里可自行修改
        const altClickScrollHeight = 34 * 3;
        
        // 重叠高度,当上下滚动时,有一部分重叠区域不滚动(并非完全滚动整个视窗),方便上下文衔接,可根据自己需要修改
        const overlap = 40;
    
        // 不支持手机版
        if(isMobile()) return;
      
        // 添加toolbar按钮
        whenElementExist('#toolbar .fn__ellipsis').then((el)=>{
            if(!el) return;
            const pageDownBtnHtml = `<div data-menu="true" id="pageDownBtn" class="toolbar__item ariaLabel" aria-label="点击向下翻页" data-location="right"><svg style=""><use xlink:href="#iconArrowDown"></use></svg></div>`;
            el.insertAdjacentHTML('afterend', pageDownBtnHtml);
            const pageDownBtn = el.nextElementSibling;
            pageDownBtn.addEventListener('click', (event) => {
                const protyleEl = getProtyleEl();
                const scrollEl = protyleEl?.querySelector('.protyle-content');
                const isCtrlPressed = (event.ctrlKey || event.metaKey) && !event.shiftKey && !event.altKey;
                const isAltPressed = event.altKey && !event.shiftKey && !event.ctrlKey && !event.metaKey;
                const isAltShiftPressed = event.altKey && event.shiftKey && !event.ctrlKey && !event.metaKey;
                // ctrl+点击向下方向键按钮
                if(isCtrlPressed) scrollPage(scrollEl, true);
                // alt+点击向下方向键按钮
                else if(isAltPressed) scrollPage(scrollEl, false, altClickScrollHeight);
                // alt+shift+点击向下方向键按钮
                else if(isAltShiftPressed) scrollPage(scrollEl, true, altClickScrollHeight);
                // 直接点击向下方向键按钮
                else scrollPage(scrollEl, false);
                
            });
    
            if(isShowPageUpBtn) {
                const pageUpBtnHtml = `<div data-menu="true" id="pageUpBtn" class="toolbar__item ariaLabel" aria-label="点击向上翻页" data-location="right"><svg style="transform: scaleY(-1);"><use xlink:href="#iconArrowDown"></use></svg></div>`;
                el.insertAdjacentHTML('afterend', pageUpBtnHtml);
                const pageUpBtn = el.nextElementSibling;
                pageUpBtn.addEventListener('click', (event) => {
                    const protyleEl = getProtyleEl();
                    const scrollEl = protyleEl?.querySelector('.protyle-content');
                    scrollPage(scrollEl, true);
                });
            }
        });
    
        function scrollPage(element, isPageUp = true, amount = 0) {
          const scroller = element || window;
          const pageHeight = scroller === window 
            ? window.innerHeight 
            : scroller.clientHeight;
        
          const scrollOptions = { 
            top: isPageUp ? (amount?-amount:(-pageHeight+overlap)) : (amount?amount:(pageHeight-overlap)),
            // behavior: 'smooth' // 按需开启
          };
        
          if (scroller === window) {
            window.scrollBy(scrollOptions);
          } else {
            scroller.scrollBy(scrollOptions);
          }
        }
        function getProtyleEl() {
            return document.querySelector('#editor') || document.querySelector(`.protyle[data-id="${[...document.querySelectorAll('.layout-tab-bar [data-type="tab-header"]')]
              .reduce((max, tab) => Number(tab?.dataset?.activetime) > Number(max?.dataset?.activetime || -1) ? tab : max, null)?.dataset?.id}"]`);
        }
        function whenElementExist(selector, node = document, timeout = 5000) {
            return new Promise((resolve, reject) => {
                const start = Date.now();
                function check() {
                    let el;
                    try {
                        el = typeof selector === 'function'
                            ? selector()
                            : node.querySelector(selector);
                    } catch (err) {
                        return resolve(null);
                    }
                    if (el) {
                        resolve(el);
                    } else if (Date.now() - start >= timeout) {
                        resolve(null);
                    } else {
                        requestAnimationFrame(check);
                    }
                }
                check();
            });
        }
        function isMobile() {
            return !!document.getElementById("sidebar");
        }
    })();
    
    1 回复
    3 操作
    wilsons 在 2025-10-09 15:05:03 更新了该回帖
    wilsons 在 2025-10-09 13:32:02 更新了该回帖
    wilsons 在 2025-10-09 12:07:03 更新了该回帖
    提示,回复编辑了多次,怕你错漏了。 当前是最后次编辑。
    8V9q7V
    @8V9q7V 已更新
    wilsons
  • 其他回帖
  • 8V9q7V 1 评论
    我重新整理了下需求:

    箭头按钮功能不再保留

    • 右上角添加 按钮,点击下翻页
    • Ctrl + ↓ 上翻页
    • 上下翻页保留思源特性:github 上下翻页时留两行空间
    • Alt + ↓ 向下滚动页面(同编辑器内鼠标下滑滚轮一样的操作)
    嗯,这个需求和我已改好的不冲突,具体滚动多大,可与通过 altClickScrollHeight 和 overlap 自行调节。因为每个人的本地环境不一样,无法写死,且思源没有行概念,最小单位是块,文本块默认大概是 34 高度。
    wilsons 1
  • wilsons 1

    0.0.6 版

    改进无论是自读滚动还是模拟拖动滚动条效果,均 alt 暂停/继续,esc 退出滚动

    https://gitee.com/wish163/mysoft/blob/main/%E6%80%9D%E6%BA%90/toolbar%E5%A2%9E%E5%8A%A0%E4%B8%8A%E4%B8%8B%E7%BF%BB%E9%A1%B5%E6%8C%89%E9%92%AE.js

    image.png

    模拟拖动滚动条效果

    自滚动效果(实际不会抖动,录制失帧问题看起来抖动)


    原 0.0.5 版

    https://gitee.com/wish163/mysoft/blob/8c2684ccd08048437ee8c1d599f317ba35746553/%E6%80%9D%E6%BA%90/toolbar%E5%A2%9E%E5%8A%A0%E4%B8%8A%E4%B8%8B%E7%BF%BB%E9%A1%B5%E6%8C%89%E9%92%AE.js

    2 回复
  • 录屏,底下一行特意标记红色展示,翻页时思源会留下这一行。关联:Leave two lines space to connect when turning pages up and down · Issue #10702 · siyuan-note/siyuan

  • 查看全部回帖

推荐标签 标签

  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 8 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖
  • NetBeans

    NetBeans 是一个始于 1997 年的 Xelfi 计划,本身是捷克布拉格查理大学的数学及物理学院的学生计划。此计划延伸而成立了一家公司进而发展这个商用版本的 NetBeans IDE,直到 1999 年 Sun 买下此公司。Sun 于次年(2000 年)六月将 NetBeans IDE 开源,直到现在 NetBeans 的社群依然持续增长。

    78 引用 • 102 回帖 • 724 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 702 关注
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 8 关注
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    17 引用 • 7 回帖 • 1 关注
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    561 引用 • 677 回帖 • 1 关注
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 120 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    45 引用 • 44 回帖 • 2 关注
  • V2Ray
    1 引用 • 15 回帖 • 4 关注
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 1 关注
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    36 引用 • 200 回帖 • 54 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1708 回帖 • 1 关注
  • Wide

    Wide 是一款基于 Web 的 Go 语言 IDE。通过浏览器就可以进行 Go 开发,并有代码自动完成、查看表达式、编译反馈、Lint、实时结果输出等功能。

    欢迎访问我们运维的实例: https://wide.b3log.org

    30 引用 • 218 回帖 • 663 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 641 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    308 引用 • 773 回帖
  • 浅吟主题

    Jeffrey Chen 制作的思源笔记主题,项目仓库:https://github.com/TCOTC/Whisper

    2 引用 • 34 回帖 • 1 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    89 引用 • 150 回帖 • 1 关注
  • abitmean

    有点意思就行了

    44 关注
  • ZooKeeper

    ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 HBase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

    61 引用 • 29 回帖 • 14 关注
  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    232 引用 • 484 回帖 • 1 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 180 关注
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 667 关注
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    119 引用 • 54 回帖