Greasy Fork is available in English.
如果需要放在后台,请安装Chrome的Don't make me watch (https://chrome.google.com/webstore/detail/dont-make-me-watch/ahjofnjojbnikkffhagdddimbcmcphhh)插件,否则会被微信读书检测并且暂停时长累积
当前为
// ==UserScript==
// @name 微信读书-WEB端自动阅读插件
// @namespace http://tampermonkey.net/
// @version 2021.02.12.1
// @description 如果需要放在后台,请安装Chrome的Don't make me watch (https://chrome.google.com/webstore/detail/dont-make-me-watch/ahjofnjojbnikkffhagdddimbcmcphhh)插件,否则会被微信读书检测并且暂停时长累积
// @author 纯白约定
// @grant 纯白约定
// @include https://weread.qq.com/web/reader/*
// @require https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js
// ==/UserScript==
/* global $ */
/**
* 开启模拟阅读任务
*/
function startInterval() {
if (window.timerScroll == null) {
window.timerScroll = setInterval(function () {
const top = window.$document.scrollTop();
if (top === 0) { window.stepFlag = 1 }
window.scrollOffset += window.stepFlag * window.offsetStep
// 模拟滚动条
window.$document.scrollTop(window.scrollOffset)
// scroll后scrollTop不变,则可以切换scroll方向了
if (top == window.$document.scrollTop()) { window.stepFlag = -1 }
}, 2000)
}
// 开启翻页定时任务,每 20分钟翻下一页
if (window.timerSwitchPage == null) {
window.timerSwitchPage = setInterval(function () {
// 获取翻页方向标识值
const directionVal = checkAndComputeDirection()
console.log(directionVal)
// 37为左翻页,39为右翻页
let keyEventCode = (directionVal === -1) ? 37 : 39;
// 此时这里应该判断是否为第一章/最终章,方便往回看,形成阅读闭环
fireKeyEvent(document, 'keydown', keyEventCode);
}, 1200000)
}
}
/**
* 关闭模拟阅读任务
*/
function stopInterval() {
if (window.timerScroll != null) {
clearInterval(window.timerScroll)
window.timerScroll = null
}
if (window.timerSwitchPage != null) {
clearInterval(window.timerSwitchPage)
window.timerSwitchPage = null
}
}
window.isEnabled = false
/**
* 模拟触发 按键 事件
*
* @param {object} el
* @param {string} evtType
* @param {number} keyCode
*/
function fireKeyEvent(el, evtType, keyCode) {
let evtObj;
if (document.createEvent) {
// firefox 浏览器下模拟事件
if (window.KeyEvent) {
evtObj = document.createEvent('KeyEvents');
evtObj.initKeyEvent(evtType, true, true);
el.dispatchEvent(evtObj)
return
}
// chrome 浏览器下模拟事件
evtObj = document.createEvent('UIEvents');
evtObj.initUIEvent(evtType, true, true);
delete evtObj.keyCode;
//为了模拟keycode
if (typeof evtObj.keyCode === "undefined") {
Object.defineProperty(evtObj, "keyCode", { value: keyCode });
} else {
evtObj.key = String.fromCharCode(keyCode);
}
if (typeof evtObj.ctrlKey === 'undefined') {//为了模拟ctrl键
Object.defineProperty(evtObj, "ctrlKey", { value: true });
} else {
evtObj.ctrlKey = true;
}
el.dispatchEvent(evtObj);
return
}
//IE 浏览器下模拟事件
if (document.createEventObject) {
evtObj = document.createEventObject();
evtObj.keyCode = keyCode
el.fireEvent('on' + evtType, evtObj);
}
}
/**
* 根据开关状态 - 开启/关闭 模拟阅读任务
*
* @param {bool} isEnabled
*/
function handleInterval(isEnabled) {
if (isEnabled) {
startInterval()
return
}
stopInterval()
}
/**
* 根据插件状态获取对应配置信息
*/
window.fetchStatusConfig = function (isEnabled) {
const statusMap = {
on: {
label: 'On 🧐',
style: {
fontWeight: 'bolder',
color: 'red',
},
},
off: {
label: 'Off 😴',
style: {
fontWeight: '',
color: '#ffffff',
}
},
}
return isEnabled ? statusMap.on : statusMap.off
}
/**
* direction为翻页方向 1为往后翻 -1为往前翻
*/
/**
* 根据页面元素决定当前翻页方向
*/
window.direction = 1
function checkAndComputeDirection() {
const directionRight = 1
const directionLeft = -1
// 首页的标记元素,有该元素标识已经到达第一页
const startElement = $('.bookInfo_title')
if (startElement.length) {
window.direction = directionRight
return directionRight
}
// 尾页的标记元素,有该元素标识已经到达最后一页
const endElement = $('.readerFooter_ending')
if (endElement.length) {
window.direction = directionLeft
return directionLeft
}
return window.direction
}
/**
*
* 初始化UI元素
*
* @param {object} $body
*/
function initUIElement($body) {
const statusOff = window.fetchStatusConfig(window.isEnabled)
$body.append('<span id="switch" title="点击切换阅读状态" style="font-size: 20px;opacity: 0.7;position: fixed;z-index: 1024;top: 100px;right: 100px;/* width: 100px; *//* height: 50px; */cursor: pointer;">' + statusOff.label + '</span>');
$('#switch').on('click', function () {
window.isEnabled = !window.isEnabled
const statusNew = window.fetchStatusConfig(window.isEnabled)
Object.assign(this.style, statusNew.style)
this.textContent = statusNew.label
handleInterval(window.isEnabled)
})
}
/**
* 启动脚本
*/
(function () {
'use strict';
window.$body = $('body')
window.$document = $(document)
window.scrollOffset = 0
window.stepFlag = 1
window.offsetStep = 1
initUIElement(window.$body);
})();