您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Preloads Dynasty Reader pages.
// ==UserScript== // @name Dynasty Preloader // @namespace http://tampermonkey.net/ // @version 0.3.5.1 // @description Preloads Dynasty Reader pages. // @author mcpower // @match http://dynasty-scans.com/chapters/* // @grant none // @license GPLv3 // ==/UserScript== // Dynasty Preloader - a UserScript to preload pages in Dynasty Reader // Copyright (C) 2017 mcpower // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // This preloads Dynasty Reader pages and indicates it with colours. // Red means it's in the queue, but it hasn't preloaded it yet. // Yellow means it's currently preloading. // Green means it's preloaded. // // If you wish, you can also preload all pages by clicking on the "Load All" button // to the right of the "Fullscreen" button. // Change these variables if you wish. // lookahead is the number of pages to load ahead of you. // lookbehind // max_concurrent is the maximum number of image requests at any one time. // Turn this down if you get loading screens, even though the page has been preloaded. const lookahead = 4; const lookbehind = 2; const max_concurrent = 5; (function () { "use strict"; let queue = []; // page objects let images = []; // stack/queue of Image objects to be used after they've been loaded const states = { default: -1, queued: 0, loading: 1, loaded: 2 }; const state_classes = { [states.default]: "", [states.queued]: "queued", [states.loading]: "loading", [states.loaded]: "loaded" }; const state_list = Object.keys(states); const css_text = ".queued{background:#ebccd1} .loading{background:#fcf8e3} .loaded{background:#dff0d8}"; // initialise images with the image elements // define the onload event so we don't have to define it later // just set any Image.page then Image.src and then it'll be all good function img_onload(event) { const img = event.path[0]; const page = img.page; page.state = states.loaded; images.push(img); update_style(page); check_queue(); } for (let i = 0; i < max_concurrent; i++) { const cur_img = new Image(); cur_img.onload = img_onload; images.push(cur_img); } function update_style(page) { if (page.state === page.styled_state) return; const cl = page.element.classList; if (page.styled_state !== states.default) { cl.remove(state_classes[page.styled_state]); } cl.add(state_classes[page.state]); page.styled_state = page.state; } // To load stuff, chuck it onto the queue and call this function function check_queue() { while (images.length > 0 && queue.length > 0) { load(queue.shift()); } } // Actually, to check stuff on the queue you should probably use this function // You still need to call check_queue though. function chuck_on_queue(page) { if (page.state === states.loading || page.state === states.loaded) return; page.state = states.queued; queue.push(page); update_style(page); } function load(page) { if (page.state === states.loading || page.state === states.loaded) return; const img = images.pop(); page.state = states.loading; update_style(page); img.page = page; img.src = page.image; } // loads `lookahead` pages after the current page and `lookbehind` before. function load_lookahead() { let cur_page; switch (window.location.hash) { case "#last": cur_page = window.pages.length; break; case "": cur_page = 1; break; default: cur_page = parseInt(window.location.hash.substr(1)); } // clamp juust in case cur_page = Math.min(window.pages.length, Math.max(1, cur_page)); const cur_index = cur_page - 1; // Always load lookahead before lookbehind for (let i = cur_index; i <= cur_index + lookahead && i < window.pages.length; i++) { chuck_on_queue(window.pages[i]); } for (let i = cur_index - 1; i >= cur_index - lookbehind && i >= 0; i--) { chuck_on_queue(window.pages[i]); } check_queue(); } // loads all pages function load_all() { window.pages.forEach(chuck_on_queue); check_queue(); return false; } // inject the CSS we want const css = document.createElement("style"); css.innerHTML = css_text; document.body.appendChild(css); // precalculate all the DOM elements const pages_list = document.getElementById("prev_link").parentElement; for (let i = 0; i < window.pages.length; i++) { window.pages[i].element = pages_list.children[i+1]; window.pages[i].state = states.default; window.pages[i].styled_state = states.default; } // create the "Load All" button const load_button = document.createElement("a"); load_button.className = "btn btn-mini"; load_button.innerHTML = "Load All"; load_button.href = "#"; load_button.onclick = load_all; document.getElementById("fullscreen").insertAdjacentElement("afterend", load_button); // lookahead stuff window.addEventListener("hashchange", load_lookahead); load_lookahead(); }());