您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
增加一些辅助阅读功能(自用)。
当前为
// ==UserScript== // @name 嗨皮漫畫閱讀輔助 // @name:zh-CN 嗨皮漫画阅读辅助 // @version 2.2 // @description 增加一些輔助閱讀功能(自用)。 // @description:zh-CN 增加一些辅助阅读功能(自用)。 // @author tony0809 // @match *://m.happymh.com/* // @icon https://m.happymh.com/favicon.ico // @grant none // @run-at document-end // @license GPL // @namespace https://greasyfork.org/users/20361 // ==/UserScript== (() => { 'use strict'; const options = { //true 開啟,false 關閉 kn: true, //按鍵盤右方向鍵前往下一話。 kp: true, //按鍵盤左方向鍵前往上一話。 dn: true, //雙擊前往下一話,方便手機使用。 kdn: [false, 300], //按住空白鍵超過幾毫秒下一話。 nE: true, //閱讀頁底部增加更新頁和收藏頁的按鈕。 pl: true, //閱讀頁預讀全部圖片。 hE: true, //隱藏閱讀頁頂部的公告。 ion: [false, 200], //下一話按鈕完全進入視窗可視範圍內時經過幾ms後自動下一話。 lM: true, //更新頁自動點擊載入更多。 list: true, //目錄頁自動展開全部章節。 oint: true //在新分頁打開漫畫鏈接。 }, ge = e => document.querySelector(e), gae = e => document.querySelectorAll(e), gx = x => document.evaluate(x, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue, lp = location.pathname, read = /^\/reads\/\w+\/\d+$/.test(lp), latest = /^\/latest$/.test(lp), list = /^\/manga\/\w+$/.test(lp), book = /^\/bookcase$/.test(lp), rank = /^\/rank/.test(lp), user = /^\/user/.test(lp), addGlobalStyle = css => { let style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; document.head.appendChild(style); }, readCss = ` article img { width: auto !important; height: auto !important; max-width: 100% !important; display: block !important; margin: 0 auto !important } `, hasTouchEvents = () => { if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) { return true } return false }, loadMore = e => { let LoadMore = ge(e); if (hasTouchEvents()) { let dispatchTouchEvent = (ele, type) => { let touchEvent = document.createEvent('UIEvent'); touchEvent.initUIEvent(type, true, true); touchEvent.touches = [{ clientX: 1, clientY: 1 }]; ele.dispatchEvent(touchEvent); } dispatchTouchEvent(LoadMore, "touchstart"); dispatchTouchEvent(LoadMore, "touchend"); console.log('嗨皮漫畫模擬觸控點擊'); } else { LoadMore.click(); console.log('嗨皮漫畫模擬點擊'); } }, openInNewTab = () => document.querySelectorAll('.home-banner a:not([target=_blank]),.manga-rank a:not([target=_blank]),.manga-cover a:not([target=_blank])').forEach(a => { a.setAttribute('target', '_blank'); }), preLoad = lp => { let lps = lp.split('/'); let mangaCode = lps[2]; let mangaId = lps[3]; let apiUrl = `https://m.happymh.com/v2.0/apis/manga/read?code=${mangaCode}&cid=${mangaId}`; fetch(apiUrl).then(res => res.json()).then((res) => { console.log('嗨皮漫畫本話數據\n', res); let imgs = res.data.scans; for (let i = 0; i < imgs.length; i++) { if (imgs[i].n > 0) { break } let img = new Image(); img.src = imgs[i].url; } }); }; if (options.oint && !read && !list && !user) { openInNewTab(); console.log('嗨皮漫畫在新分頁打開漫畫鏈接'); new MutationObserver(() => { openInNewTab(); }).observe(document.body, { childList: true, subtree: true }); } if (options.lM && latest) { new IntersectionObserver((e) => { if (e[0].isIntersecting) { loadMore('.more-div-btn'); console.log('載入更多'); } }).observe(ge('.more-div-btn')); } if (options.list && list) { ge('#expandButton').click(); console.log('嗨皮漫畫自動展開目錄'); } if (options.hE && read) { addGlobalStyle('#root>div>header+div{display:none!important}'); } if (options.kn && read) { document.addEventListener('keydown', (e) => { let key = window.event ? e.keyCode : e.which; if (key == '39') { let n = gx("//a[span[text()='下一话' or text()='下一話'] and contains(@href,'reads')]"); if (n) { location.href = n.href; } else { alert('沒有下一话了!'); } } }); } if (options.kp && read) { document.addEventListener('keydown', (e) => { let key = window.event ? e.keyCode : e.which; if (key == '37') { let p = gx("//a[span[text()='上一话' or text()='上一話'] and contains(@href,'reads')]"); if (p) { location.href = p.href; } else { alert('沒有上一话了!'); } } }); } if (options.dn && read) { document.addEventListener('dblclick', () => { let n = ge('footer a'); location.href = n.href; }); } if (options.kdn[0] && read) { let timeId; document.addEventListener('keypress', (e) => { let key = window.event ? e.keyCode : e.which; if (key = 32) { let n = gx("//a[span[text()='下一话' or text()='下一話'] and contains(@href,'reads')]"); if (n) { timeId = setTimeout(() => { location.href = n.href; }, options.kdn[1]) } else { timeId = setTimeout(() => { alert('沒有下一話了!'); }, options.kdn[1]) } } }); document.addEventListener('keyup', (e) => { let key = window.event ? e.keyCode : e.which; if (key = 32) { clearTimeout(timeId); } }); } if (options.nE && read) { setTimeout(() => { let f = ge('footer>article'); let c1 = f.firstChild.cloneNode(true); c1.firstChild.href = '/latest'; c1.firstChild.firstChild.innerText = '更新'; f.appendChild(c1); let c2 = f.firstChild.cloneNode(true); c2.firstChild.href = '/bookcase'; c2.firstChild.firstChild.innerText = '收藏'; f.appendChild(c2); let p = ge('footer p:nth-child(2)>a[href*=reads]'); if (p) { p.classList.add('MuiButton-containedPrimary'); } let n = ge('footer a[href*=readMore]'); if (n) { n.classList.remove('MuiButton-containedPrimary'); n.firstChild.innerText = '^_^感谢您的阅读~已经没有下一话了哦~'; } }, 4000); } if (options.pl && read) { addGlobalStyle(readCss); let loop = setInterval(() => { let iL = ge('[id^=imageLoader]'); if (iL) { clearInterval(loop); preLoad(lp); } }, 100); console.log('嗨皮漫畫預讀全部圖片'); } if (options.ion[0] && read) { setTimeout(() => { console.log('嗨皮漫畫下一話按鈕完全進入可視範圍內時自動下一話'); new IntersectionObserver((e) => { if (e[0].isIntersecting) { setTimeout(() => { let n = gx("//a[span[text()='下一话' or text()='下一話'] and contains(@href,'reads')]"); if (n) location.href = n.href; }, options.ion[1]) } }, { threshold: 1, }).observe(ge('footer a')); }, 4000); } })();