🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

微信读书自动阅读

微信读书阅读自动滚动, 触底自动翻页

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

You will need to install an extension such as Tampermonkey to install this script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name		微信读书自动阅读
// @name:en		WeChatReadAutoScroll
// @description		微信读书阅读自动滚动, 触底自动翻页
// @description:en	微信读书阅读自动滚动, 触底自动翻页
// @version		1.0.0
// @match		https://weread.qq.com/web/reader/*
// @author		Yiero
// @icon		https://weread.qq.com/favicon.ico
// @namespace		https://github.com/AliubYiero/TamperMonkeyScripts/
// @license		GPL
// @grant		GM_registerMenuCommand
// @grant		GM_unregisterMenuCommand
// @grant		GM_setValue
// @grant		GM_getValue
// @grant		GM_deleteValue
// @grant		GM_listValues
// @run-at		document-idle
// ==/UserScript==
var __defProp = Object.defineProperty;

var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, {
    enumerable: true,
    configurable: true,
    writable: true,
    value: value2
}) : obj[key] = value2;

var __publicField = (obj, key, value2) => {
    __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value2);
    return value2;
};

class Info {
    constructor(projectName) {
        __publicField(this, "projectName");
        __publicField(this, "header");
        this.projectName = projectName;
        this.header = `[${projectName}]`;
    }
    log(...msg) {
        (() => {})(...this.contentInfo(...msg));
    }
    info(...msg) {
        console.info(...this.contentInfo(...msg));
    }
    warn(...msg) {
        console.warn(...this.contentInfo(...msg));
    }
    error(...msg) {
        console.error(...this.contentInfo(...msg));
    }
    contentInfo(...msg) {
        return [ this.header, `[${(new Date).toLocaleString("zh-ch")}]`, ...msg ];
    }
}

function MathCeilFloat(number, decimal = 0) {
    decimal = Math.pow(10, decimal);
    return Math.ceil(number * decimal) / decimal;
}

function isReachedPageBottom() {
    const {scrollTop: scrollTop, clientHeight: clientHeight, scrollHeight: scrollHeight} = document.documentElement;
    return scrollTop + clientHeight >= scrollHeight;
}

class ScrollOptionsImpl {
    constructor() {
        __publicField(this, "_delayPerMs", 0);
        __publicField(this, "_frameDuration", 0);
        __publicField(this, "_framePerSecond", 0);
        __publicField(this, "_movementDistancePerSecond", 0);
    }
    get delayPerMs() {
        return this._delayPerMs;
    }
    set delayPerMs(value) {
        if (typeof value === "string") {
            const scrollPageDuration = window.innerHeight / this.movementDistancePerSecond * 1e3;
            print.log(scrollPageDuration, this.movementDistancePerSecond);
            try {
                this._delayPerMs = eval(value.replace("auto", String(scrollPageDuration)));
            } catch (e) {
                this._delayPerMs = scrollPageDuration;
            }
        } else {
            this._delayPerMs = value;
        }
    }
    get movementDistancePerFrame() {
        return MathCeilFloat(this.movementDistancePerSecond / this.framePerSecond, 3);
    }
    get frameDuration() {
        return MathCeilFloat(1e3 / this._frameDuration);
    }
    get framePerSecond() {
        return this._framePerSecond;
    }
    set framePerSecond(value2) {
        this._framePerSecond = value2;
    }
    get movementDistancePerSecond() {
        return this._movementDistancePerSecond;
    }
    set movementDistancePerSecond(value2) {
        this._movementDistancePerSecond = value2;
    }
}

class GlobalAutoScroll {
    constructor(movementDistancePerSecond, delayPerMs = "auto", framePerSecond = 60) {
        __publicField(this, "options", new ScrollOptionsImpl);
        __publicField(this, "timer");
        this.options.movementDistancePerSecond = movementDistancePerSecond;
        this.options.delayPerMs = delayPerMs;
        this.options.framePerSecond = framePerSecond;
    }
    open() {
        if (this.timer) {
            this.close();
        }
        scrollStatusStorage.set("scrolling");
        print.info("等待滚动: ", this.options.delayPerMs);
        this.timer = window.setTimeout((() => {
            this.timer = window.setInterval((() => {
                this.scroll();
                if (isReachedPageBottom()) {
                    this.close();
                }
            }), this.options.frameDuration);
        }), this.options.delayPerMs);
    }
    close() {
        scrollStatusStorage.set("scroll-end");
        clearTimeout(this.timer);
        clearInterval(this.timer);
        this.timer = void 0;
    }
    scroll() {
        const movementDistancePerFrame = this.options.movementDistancePerFrame;
        scrollBy(0, movementDistancePerFrame);
    }
}

class GMConfigMenu {
    constructor(callback) {
        __publicField(this, "menuId", 0);
        __publicField(this, "callback");
        this.callback = callback;
    }
    open(title) {
        if (this.menuId) {
            this.close();
        }
        this.menuId = GM_registerMenuCommand(title, this.callback);
    }
    close() {
        GM_unregisterMenuCommand(this.menuId);
        this.menuId = 0;
    }
}

class LocalStorage {
    constructor(key) {
        __publicField(this, "key");
        this.key = key;
    }
    get(defaultValue) {
        return localStorage.getItem(this.key) || defaultValue || "";
    }
    remove() {
        const oldValue = this.get();
        const newValue = void 0;
        dispatchEvent(new CustomEvent("storageUpdate", {
            detail: {
                key: this.key,
                newValue: newValue,
                oldValue: oldValue
            }
        }));
        localStorage.removeItem(this.key);
    }
    set(value2) {
        const oldValue = this.get();
        const newValue = value2;
        dispatchEvent(new CustomEvent("storageUpdate", {
            detail: {
                key: this.key,
                newValue: newValue,
                oldValue: oldValue
            }
        }));
        localStorage.setItem(this.key, value2);
    }
}

class SessionStorage {
    constructor(key) {
        __publicField(this, "key");
        this.key = key;
    }
    get(defaultValue) {
        return sessionStorage.getItem(this.key) || defaultValue || "";
    }
    remove() {
        const oldValue = this.get();
        const newValue = void 0;
        dispatchEvent(new CustomEvent("storageUpdate", {
            detail: {
                key: this.key,
                newValue: newValue,
                oldValue: oldValue
            }
        }));
        sessionStorage.removeItem(this.key);
    }
    set(value2) {
        const oldValue = this.get();
        const newValue = value2;
        dispatchEvent(new CustomEvent("storageUpdate", {
            detail: {
                key: this.key,
                newValue: newValue,
                oldValue: oldValue
            }
        }));
        sessionStorage.setItem(this.key, value2);
    }
}

new MouseEvent("mouseenter", {
    button: 0,
    bubbles: true,
    cancelable: true,
    clientX: 819,
    clientY: 413
});

new MouseEvent("mousedown", {
    bubbles: true,
    cancelable: true,
    button: 0
});

new MouseEvent("mouseup", {
    bubbles: true,
    cancelable: true,
    button: 0
});

new MouseEvent("click", {
    bubbles: true,
    cancelable: true,
    button: 0
});

function fireKeyEvent(el = document, evtType, keyCode) {
    let evtObj;
    if (document.createEvent) {
        if (window.KeyEvent) {
            evtObj = document.createEvent("KeyEvents");
            evtObj.initKeyEvent(evtType, true, true);
            el.dispatchEvent(evtObj);
            return;
        }
        evtObj = document.createEvent("UIEvents");
        evtObj.initUIEvent(evtType, true, true);
        delete evtObj.keyCode;
        if (typeof evtObj.keyCode === "undefined") {
            Object.defineProperty(evtObj, "keyCode", {
                value: keyCode
            });
        } else {
            evtObj.key = String.fromCharCode(keyCode);
        }
        if (typeof evtObj.ctrlKey === "undefined") {
            Object.defineProperty(evtObj, "ctrlKey", {
                value: true
            });
        } else {
            evtObj.ctrlKey = true;
        }
        el.dispatchEvent(evtObj);
        return;
    }
}

const print = new Info("WeChatReadAutoScroll");

const scrollStatusStorage = new SessionStorage("scrollStatus");

(async () => {
    const scrollSpeedController = new GMConfigMenu((() => {
        const result = prompt("页面滚动速度(px/s)");
        if (!result) {
            return;
        }
        localStorage.setItem("scrollSpeed", result);
    }));
    scrollSpeedController.open("[配置] 滚动速度");
    const scrollDelayController = new GMConfigMenu((() => {
        const result = prompt("滚动开启延时 ( auto | (auto / 2) | number ) (ms)");
        if (!result) {
            return;
        }
        localStorage.setItem("scrollDelay", result);
    }));
    scrollDelayController.open("[配置] 滚动开启延时");
    function scrollSwitch() {
        let globalAutoScroll;
        const scrollOpenController = new GMConfigMenu(scrollOpenMenuCallback);
        function scrollOpenMenuCallback() {
            const scrollSpeedStorage = new LocalStorage("scrollSpeed");
            const scrollDelayStorage = new LocalStorage("scrollDelay");
            globalAutoScroll = new GlobalAutoScroll(+scrollSpeedStorage.get("100"), scrollDelayStorage.get("auto"), 60);
            globalAutoScroll.open();
            window.addEventListener("click", (() => {
                globalAutoScroll.close();
            }), {
                once: true
            });
            scrollOpenController.close();
            scrollCloseController.open("关闭滚动");
        }
        const scrollCloseController = new GMConfigMenu((() => {
            globalAutoScroll.close();
            scrollCloseMenuCallback();
        }));
        function scrollCloseMenuCallback() {
            scrollCloseController.close();
            scrollOpenController.open("开启滚动");
        }
        scrollOpenController.open("开启滚动");
        scrollStatusStorage.set("scroll-start");
        window.addEventListener("storageUpdate", (e => {
            const event = e;
            if (event.detail.key === "scrollStatus" && event.detail.newValue === "scroll-end") {
                scrollCloseMenuCallback();
                if (isReachedPageBottom()) {
                    fireKeyEvent(document, "keydown", 39);
                    scrollOpenMenuCallback();
                }
            }
        }));
    }
    scrollSwitch();
})();