您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Infinite scrolling for galleries in e-hentai and exhentai
当前为
// ==UserScript== // @name Panda Infinite Scroll // @description Infinite scrolling for galleries in e-hentai and exhentai // @namespace https://gist.github.com/ytjchan // @author ytjchan // @version 1.0.0 // @include *://e-hentai.org/* // @include *://exhentai.org/* // @exclude *://e-hentai.org/g/* // @exclude *://e-hentai.org/s/* // @exclude *://exhentai.org/g/* // @exclude *://exhentai.org/s/* // ==/UserScript== // Current page (0-indexed) let url = new URL(window.location); if (url.pathname.includes("tag") && isNaN(url.pathname.split("/").slice(-1)[0])) url.href += "/0"; url.setPage = (url.pathname.includes("tag"))? page => url.href = url.href.replace(/\/[^\/]*$/, "/"+page) : page => url.searchParams.set("page", page); let currentPage = (url.pathname.includes("tag"))? (parseInt(url.pathname.split("/").slice(-1)[0]) || 0) : (parseInt(url.searchParams.get("page")) || 0); // Restore current page in case of page back if (document.getElementsByClassName("page-anchor").length !== 0) currentPage = Math.max(...Array.from(document.getElementsByClassName("page-anchor")).map(el => parseInt(el.getAttribute("data-page")))); // Max page let pageBtns = document.querySelectorAll(".ptt td"); let maxPage = parseInt(pageBtns[pageBtns.length-2].textContent) - 1; // Detect if bottom of page reached let observer = new IntersectionObserver(fetchNextPage, { threshold: 1.0 }); observer.observe(document.querySelector(".ptb")); // Alert area let flex = document.createElement("div"); flex.setAttribute("style", "display: flex;flex-direction: column;align-items: flex-end;position: fixed;top: 0;right: 0;z-index: 10;"); document.getElementsByTagName("body")[0].appendChild(flex); createScrollAlert(currentPage); let inProcess = false; function fetchNextPage() { if (currentPage >= maxPage) { observer.disconnect(); createAlert("Last page reached", 5000, "#0FF"); return; } if (inProcess) return; inProcess = true; url.setPage(++currentPage); fetch(url.href) .then(res => res.text()) .then(html => { let parent = document.querySelector(".gl1t, .itg tr").parentNode; let dummy = document.createElement("html"); dummy.innerHTML = html; parent.innerHTML += Array.from(dummy.querySelectorAll(".gl1t, .itg tr")).reduce((prev, el, i) => { if (i === 0) { el.classList.add("page-anchor"); el.setAttribute("data-page", currentPage); } return prev += el.outerHTML; }, ""); createScrollAlert(currentPage); inProcess = false; }) .catch(e => createAlert(e, 5000, "#F00")); } function createAlert(msg, timeout, bgColor = "#EEE") { let div = document.createElement("div"); div.textContent = msg; div.setAttribute("style", "padding: 0.5em;margin-bottom: 0.1em;font-size: 1.25em;background-color: "+bgColor+";color: #000"); flex.appendChild(div); setTimeout(()=>div.remove(), timeout); return div; } function scrollToPage(page) { if (page > currentPage) { alert("Page not loaded yet"); return; } try { document.querySelector(".page-anchor[data-page='"+page+"']").scrollIntoView(); } catch (e) { // page anchor does not exist document.documentElement.scrollTop = 0; } } // display clickable page alert as 1-indexed function createScrollAlert(page) { createAlert((page+1)+" / "+(maxPage+1), 5000, "#0F0") .addEventListener("click", scrollToPage.bind(null, page)); // display as 1-indexed }