首页 > 其他分享 >微信读书网页版终于能自动阅读了!

微信读书网页版终于能自动阅读了!

时间:2024-04-08 15:13:24浏览次数:29  
标签:网页 翻页 微信 自动 读书 阅读 滚轴 config

微信读书移动端

不知道有多少小伙伴使用微信读书App的? 在移动端有个非常好用的功能叫自动阅读. 这个功能解放了双手, 让阅读更加沉浸式.

image-20240331201916375

微信读书网页端痛点

但是我更喜欢用电脑看书, 电脑版的微信读书就是个网页, 非常的简洁, 除了阅读书籍外没有任何功能. 包括自动阅读. 这就很麻烦了, 这对我来说真的是非常刚需的功能, 没有了自动阅读我都看不下去了, 时不时就要拿鼠标去点一下滚轴. 我想应该不止我一个人遇到了这个问题, 所以先搜索了下浏览器插件.

image-20240404235527906

很遗憾, 看起来也就第一个用的人多点. 但是看起来都不包含自动阅读的能力. 看样子只能自己写一个了.

原谅我词穷, 我真想不到该起什么名字...就和他们同名也无妨, 反正我只想解决我自己的需求.

设计思路

结合日常阅读的习惯, 我设计了以下几个功能点.

  • 开启/关闭自动阅读
  • 调整自动阅读速度
  • 开启自动阅读时, 有时需要手动让滚轴往上/往下走一些
  • 保存配置, 避免每次都要重新设置

首先我倾向于选择键盘按键来实现这些功能, 因为按下一个按键一定比用手抓到鼠标再点击目标要快的多. 经常玩游戏的同学都很熟悉WASD的键位, 在DNF中, D是向右走, 也就是向前行. 而A则是往回走. 因此, 我设定A是降低阅读速度, D则是增加阅读速度.

image-20240331205054961

那么剩下的W和S则对应了往上和往下滚动一小段距离. 这个需求场景是当我们在阅读时, 可能因为某个片段有些复杂或过于简单, 而导致我们想短暂地调整下阅读进度.

而开启和关闭自动阅读, 则是定在了'x'的键位上. 因为我小时候玩的一款叫彩虹岛的网游就是按X攻击的. 因此X在我印象中充满了战斗气息. 怎么样, 我这套键位设计的很合理吧!

image-20240331205842798

成果展示

自动阅读

正如前面我们所约定的那样, 我们打开一本书进行阅读时, 页面右下角会提示你

image-20240405000623585

只需要按下x, 就会开启自动阅读了. 并且这个速度还是可调的

设置中心

不止是这样哦. 因为我显示器比较大, 我发现页面两侧有很大的空白. 所以我还设置了屏占比的功能

这个功能其实是和另一个微信助手借鉴的. 但是他们设置的有bug. 视频版里有详细介绍.

在进入微信读书的时候, 我的插件会在左上角放一颗七龙珠.

至于为什么是七龙珠...没啥特别的原因. 我真就是需要icon的时候突然想起七龙珠了, 就整了一颗放这. 可以点击这颗龙珠召唤, 不是, 点击打开设置面板.

image-20240405000424062

屏占比

官方默认就是1000px的, 最大可以设置2000px. 在我的大显示器上几乎全屏铺满了. 我拿手机拍摄大家对比下.

image-20240405001845536

image-20240405001851578

勿扰模式

前文展示了在调整速度、切换界面的时候右下角是有toast提示的. 有时候这些额外的元素可能会吸引我们的注意, 而插件的用法非常简单, 并不需要反复提醒. 因此, 在设置中我们可以开启勿扰模式, 世界都会变得安静.

image-20240405002027668

菜单自定义显隐

不知道大家有没有感觉这一排的icon很鸡肋

image-20240405164958820

这些icon常驻在页面中, 但是谁会没事干天天改字号? 谁会亮色和暗色主题来回切换? 在我看来就是影响我沉浸式阅读的存在. 因此我做了2个改动. 第一个改动是将其位置从主体页面中移除, 放在了header区域

image-20240405165143446

其次, 正如我前文所说, 这大部分的icon都用不着. 对我来说, 只有目录这个功能确实偶尔会用到. 因为可能对某些章节不感兴趣, 想跳过去. 所以, 我就对他做了个自定义显隐功能.

image-20240405165330263

image-20240405165355336

怎么样? 是不是更合理一些了?

实现方案

浏览器扩展开发, 我建议使用Plasmo进行开发. 他是一个浏览器扩展开发的解决方案, 允许你使用 React 进行开发, 并提供了HMR、打包等一系列的开箱即用的方案. 官方文档写的非常通俗易懂. 不过你需要先了解基础的浏览器插件开发知识, 如Background、Content Script等.

接下来我们来思考如何实现前文中提到的业务. 这里我想挑几个我觉得值得一聊的内容详细说说.

自动阅读

如何让页面自动阅读呢? 转化成技术的用词就是: 如何让滚轴高度稳定的往下滚动. 这个比较简单, 思路如下

  • 获取到页面的滚轴高度
  • 将滚轴高度设置为基于之前获取到的滚轴高度再+上一定的滚轴高度

但是这里有个技术细节, 假定我们的代码片段如下

// speed 是用户设置的阅读速度
let speed;
function addScrollTop(): void {
  let recordScroll = document.documentElement.scrollTop;
  recordScroll += speed;
  document.documentElement.scrollTop = recordScroll;
}

现在当我们调用addScrollTop时, 就会往下滚动一些距离. 那么请问, 调用一次也就一次, 调用两次也就两次, 如何让他不停的调用自己呢? 可能有同学会想到setInterval, 那现在我们来思考一个场景.

当我在使用微信读书的时候, 突然有人给我发了条电脑微信, 我中断了读书的状态回复微信, 结束后再回来, 请问刚刚的自动阅读是不是始终在自动阅读? 如果你使用的是定时器, 那么一定是在继续阅读的. 这将导致你必须往回寻找刚刚的阅读进度.

那么我是如何解决这个问题的呢. 我使用的是requestAnimationFrame, 这个API可以让你的显示器窗口不可见时, 暂停自动阅读. 也就是说, 当我读到某个进度而划走窗口做别的事情时, 再回来, 进度可以无缝衔接. 那么什么叫显示器窗口不可见呢?

image-20240331213523412

其实就是几个桌面窗口的切换. 但是如果我的浏览器和微信都在同一个窗口下, 那么我点击微信, 也就是浏览器失焦的时候, 会停止自动阅读吗? 答案是不会的. 这符合用户习惯, 因为我无法判断用户失焦时是不是期望停止自动阅读. 毕竟阅读时顺手回几句简短的消息也是很正常的操作. 但是切换窗口则通常是有更复杂的任务要执行, 短时间回不来.

判断翻页

之前在完成初版的时候出现了一个bug, 当我阅读完一整页的内容时, 进行翻页. 注意, 翻页是需要手动操作的. 按下右方向键就可以了, 这是官方提供的. 在翻页后, 阅读进度会闪现到很后面. 我们不难分析表现可以推测出, 问题的原因是第一页结束的时候, 滚轴当前的位置比如是800, 翻页后从0开始看. 但因为代码中记得刚刚是看到了800的高度, 所以下一个渲染时间点就把进度调整到了800+speed的位置. 因此, 我们需要在翻页时重置记忆的滚轴高度. 那么怎么判断翻页了呢? 通过对页面的研发不难发现, 当章节变化的时候, 页面上会显示章节的标题.

image-20240331214714087

那么我们只需要监听这个章节的DOM内容变化即可. 我们需要借助MutationObserver的API

const chapterTitle = document.querySelector('.readerTopBar_title_chapter');
const documentObserver = new MutationObserver(function () {
	// 重置滚轴高度
});
// 对章节标题 DOM 进行监听
documentObserver.observe(chapterTitle, {
  attributes: true,
  childList: true,
  characterData: true,
  subtree: true,
});

保存频率过高导致报错

自动阅读的速度、屏占比等都是自动保存的. 每次更改阅读速度, 都会直接保存在浏览器当中.

// 每次需要保存配置的时候就调用该方法
function updateConfig(config) {
  // storage 是 Plasmo 提供的存储模块
  storage.set('config', config);
}

那假如我连续几十次调整速度, 这个函数就被调用了几十次, 然后控制台就报错了.

This request exceeds the MAX_WRITE_OPERATIONS_PER_MINUTE quota

查了下资料, 大概意思是说浏览器不允许插件在短时间内大量的执行存储操作. 那么显然我们就需要上防抖了. 为此我借助了Rxjs中的防抖操作符, 玩Angular的同学应该很熟悉.

const updateConfig$ = new Subject<Config>();
// 更新操作任你调, 我只执行最后一次.
updateConfig$.pipe(debounceTime(500)).subscribe((config: Config) => {
  storage.set('config', config);
});

function updateConfig(config) {
  updateConfig$.next(config);
}

源码中我最终移除了这个方案, 因为只因为这一个场景引入一个lib感觉不太优雅. 我手动用定时器来解决这个问题. 反正目的都是一样的, 能实现防抖就可以.

结语

这个插件只是为了方便我自己使用微信读书. 如果你也需要微信读书, 快来体验沉浸式阅读吧! 目前已上架下列应用商店, 项目地址: https://github.com/Eve-Sama/weread-web-extension


我是前夕, 专注于前端和成长, 希望我的内容可以帮助到你. 公众号: 前夕小课堂

image-20240403101717261

本文禁止转载!

标签:网页,翻页,微信,自动,读书,阅读,滚轴,config
From: https://www.cnblogs.com/evesama/p/18121197

相关文章

  • 使用高德微信小程序插件实现精准获取打卡位置
    由于微信小程序的 getFuzzyLocation 误差太大不得不改用高德微信sdk使用方法:一、下载 sdk相关下载-微信小程序插件|高德地图API二、引入 sdk//引入varamapFile=require('..­/..­/libs/amap-wx.js');Page({onLoad:function(){varthat=this;......
  • 【对接方案】低代码对接微信公众号自动回复消息
    前言相信大家都有关注过不少微信公众号,其中有很多微信公众号提供了自动回复消息的功能,用户给微信公众号发送消息时,微信公众号会自动回复对应的消息,比如下图:接下来,小编就为大家介绍一下如何使用葡萄城公司的企业级低代码开发平台——活字格实现微信公众号自动回复消息。环境准......
  • 小白如何制作微信小程序的分享功能
    制作微信小程序的分享功能主要涉及以下几个步骤:注册小程序账号和配置开发环境添加分享按钮和监听分享事件获取分享详细信息自定义分享内容实现转发功能下面将逐步详细介绍这些步骤,并提供代码案例。一、注册小程序账号和配置开发环境登录微信公众平台(https://mp.weixin.qq.c......
  • 使用微信小程序开发制作一个简易的在线预约应用
    微信小程序在线预约应用的开发可以分为以下几个步骤:项目初始化首先,我们需要在微信开发者工具中创建一个新的小程序项目。在创建项目时,可以选择使用小程序官方提供的模板,也可以选择自己从零开始开发。创建完成后,可以在项目目录下看到一些默认的文件和目录,如app.json、app.js......
  • 使用微信小程序开发制作一个简易的在线投票应用
    代码案例:微信小程序在线投票应用本案例将使用微信小程序开发工具进行开发,实现一个简易的在线投票应用。该应用的主要功能包括创建投票、参与投票、查看投票结果等。创建投票用户可以输入投票主题、选项以及投票截止日期来创建一个新的投票。首先,在小程序的页面目录中创建一......
  • Springboot计算机毕业设计橙心优购微信小程序的设计与实现【附源码】开题+论文+mysql+
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着移动互联网的快速发展和普及,微信小程序作为一种新兴的移动应用形态,受到了广大用户的青睐。微信小程序不仅具备即用即走、无需安装的特点,而且能够......
  • 微信小程序下载音频
    微信现在几乎已经成为所有人的必备app,于是就有很多人在微信小程序购买了音频资源,比如英语听力,这里就教大家一个能够下载90%的小程序资源的工具:下载高手下载高手不只是能下载音频,还能下载视频和图片。这里已经打包好了下载高手链接:https://pan.baidu.com/s/1qJ81sNBzzzU0w6D......
  • Springboot计算机毕业设计财务报销微信小程序【附源码】开题+论文+mysql+程序+部署
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着移动互联网技术的飞速发展,微信小程序作为一种新型的应用形态,以其便捷、高效的特点受到了广大用户的青睐。在高等教育领域,财务管理是学校运营中不......
  • 在网页中运行js脚本有哪些方法实现???
    前端开发工作者,天天与网站页面,Js交互语言打交道,利用js语言编写的脚本,可以直接运行的在浏览器的环境中,对于初学者来说这个“直接运行”到底是在哪里运行的呢?我们又如何实现在网页中运行js脚本,以及现实的方法一共有几种呢??(我反正一开始是不知道的,后面也是百度,博客上寻求答案的)具体......
  • 【求助】使用flask编写网页时遇到的问题
    @app.route('/signup',methods=['GET','POST'])defsecret():  form3=SecretForm()  ifrequest.method=='POST':    secret=form3.secret.data    ifsecret=='111111':      returnredirect(ur......