🏠 Home 

拷贝漫画简易阅读

简单的拷贝漫画阅读器,J/K 翻页,左右方向键改变章节,分号键奇偶切换,1/2 改变单双页


Install this script?
// ==UserScript==
// @name        拷贝漫画简易阅读
// @namespace   http://tampermonkey.net/
// @match       *://*.copymanga.com/comic/*/chapter/*
// @match       *://*.copymanga.org/comic/*/chapter/*
// @match       *://*.copymanga.site/comic/*/chapter/*
// @match       *://*.copymanga.tv/comic/*/chapter/*
// @match       *://*.mangacopy.com/comic/*/chapter/*
// @grant       none
// @version     1.25
// @author      chemPolonium
// @description 简单的拷贝漫画阅读器,J/K 翻页,左右方向键改变章节,分号键奇偶切换,1/2 改变单双页
// @run-at      document-end
// @license     GPLv3
// ==/UserScript==
/* jshint esversion: 6 */
/* jshint multistr: true */
(function() {
'use strict';
document.getElementsByClassName('header')[0].remove();
let comicContainerFluid = document.getElementsByClassName('container-fluid comicContent')[0];
comicContainerFluid.style.paddingRight = '0px';
comicContainerFluid.style.paddingLeft = '0px';
let comicContainer = comicContainerFluid.children[0];
comicContainer.style.marginRight = '0px';
comicContainer.style.marginLeft = '0px';
comicContainer.style.setProperty('min-width', '10px', 'important');
comicContainer.style.setProperty('max-width', '100%', 'important');
let comicList = comicContainer.children[0];
comicList.style.paddingTop = '0px';
comicList.style.marginBottom = '0px';
comicList.style.setProperty('min-width', '10px', 'important');
comicList.style.setProperty('max-width', '100%', 'important');
comicList.style.setProperty('width', '100%', 'important');
comicList.style.display = 'grid';
comicList.style.direction = 'rtl';
let comicListChildren = comicList.children;
let currentImageIndex = 0;
let comicIndex = document.getElementsByClassName('comicIndex')[0];
function refreshIndex() {
comicIndex.textContent = currentImageIndex;
}
function getImage(imageIndex) {
return comicListChildren[imageIndex].children[0];
}
function getCurrentImage() {
return getImage(currentImageIndex);
}
function moveToCurrentImage() {
if (currentImageIndex == 0) {
window.scrollTo(0, 0);
} else {
window.scrollTo(0, getCurrentImage().offsetTop);
}
}
let pageNumPerScreen = 2;
function preloadImage() {
// simulate the scroll for preload
// the script is like this: total client height / 3 < window scrollY then not load
// so first scroll Y to 0
window.scrollTo(0, 0);
for (let i = 0; i < pageNumPerScreen; i++) {
// window.dispatchEvent(scrollEvent);
window.onscroll();
// dispatch the scroll event for preload
}
// this function will scroll Y to 0
}
function moveImageIndex(x) {
let newImageIndex = currentImageIndex + x;
if (newImageIndex < comicList.children.length && newImageIndex >= 0) {
currentImageIndex = newImageIndex;
}
}
function setSingleAlign(imageIndex) {
if (pageNumPerScreen == 1)
{
comicListChildren[imageIndex].children[0].style.objectPosition = 'center';
// ('style', 'text-align: center;');
}
if (pageNumPerScreen == 2)
{
comicListChildren[imageIndex].children[0].style.objectPosition = (imageIndex % 2 == 0) ? 'left' : 'right';
}
}
function setAlign() {
for (let imageIndex = 0; imageIndex < comicListChildren.length; imageIndex++) {
setSingleAlign(imageIndex);
}
}
function setPageNumPerScreen(pageNum) {
comicList.style.gridTemplateColumns = 'repeat(' + String(pageNum) + ', 1fr)';
moveToCurrentImage();
pageNumPerScreen = pageNum;
setAlign();
}
setPageNumPerScreen(2);
function onePageDown() {
preloadImage();
moveImageIndex(pageNumPerScreen);
moveToCurrentImage();
refreshIndex();
}
function onePageUp() {
moveImageIndex(-pageNumPerScreen);
moveToCurrentImage();
refreshIndex();
}
function createTitlePage() {
let titlePage = document.createElement('li');
let titlePageDiv = document.createElement('div');
let titlePageTitle = document.createElement('p');
titlePageTitle.appendChild(document.createTextNode(document.title));
titlePageTitle.setAttribute('style', 'color: white;\
font-size: xx-large;\
max-width: 30vw;\
margin-top: 30%;\
margin-right: 20%;\
white-space: normal;');
titlePageDiv.appendChild(titlePageTitle);
titlePage.appendChild(titlePageDiv);
return titlePage;
}
function resizeImage(targetli) {
targetli.style.height = '100vh';
targetli.style.maxWidth = '100%';
targetli.firstChild.style.setProperty('height', '100%', 'important');
targetli.firstChild.style.setProperty('width', '100%', 'important');
targetli.firstChild.style.objectFit = 'contain';
}
function setAllPages() {
for (let i = 1; i < comicListChildren.length; i++) {
if (comicListChildren[i].children[0]) {
resizeImage(comicListChildren[i]);
}
}
}
let titlePage = createTitlePage();
let parityChanged = false;
function switchParity() {
if (parityChanged) {
comicListChildren[0].remove();
} else {
comicList.insertAdjacentElement('afterbegin', titlePage);
}
parityChanged = !parityChanged;
setAlign();
moveToCurrentImage();
}
let footer = document.getElementsByClassName('footer')[0];
let footerChildren = footer.children;
let prevChapterHref = footerChildren[1].children[0].href;
let nextChapterHref = footerChildren[3].children[0].href;
let chapterListHref = footerChildren[4].children[0].href;
function toggleFullScreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
}
}
}
document.addEventListener('keydown', (event) => {
switch (event.code) {
case 'ArrowRight':
window.location = nextChapterHref;
break;
case 'ArrowLeft':
window.location = prevChapterHref;
break;
case 'KeyK':
onePageUp();
break;
case 'KeyJ':
onePageDown();
break;
case 'KeyL':
window.location = chapterListHref;
break;
case 'KeyR':
setAllPages();
break;
case 'KeyF':
toggleFullScreen();
break;
case 'Semicolon':
switchParity();
break;
case 'Digit1':
setPageNumPerScreen(1);
break;
case 'Digit2':
setPageNumPerScreen(2);
break;
default:
console.log('key: ' + event.key + ' code: ' + event.code);
}
});
footer.remove();
let firstLoad = true;
const comicListObserverConfig = { childList: true };
const firstLoadCallback = () => {
if (firstLoad && comicListChildren.length > 0) {
firstLoad = false;
switchParity();
// 有时脚本加载得慢,会导致前几页来不及修改大小,因此第一次直接全设置一遍
setAllPages();
}
};
const comicListCallback = (mutationList, observer) => {
for (const mutation of mutationList) {
firstLoadCallback();
for (const targetli of mutation.addedNodes) {
resizeImage(targetli);
// 一般一次也就加载一页或两页,加载两页的话只设置最后一页的左右是不够的
setSingleAlign(comicListChildren.length - 2);
setSingleAlign(comicListChildren.length - 1);
}
}
};
const comicListObserver = new MutationObserver(comicListCallback);
comicListObserver.observe(comicList, comicListObserverConfig);
// 有的时候会出现列表加载完了,脚本还没加载上的情况,这时候 MutationObserver 会失效
// 这个时候就手动加个延时当作第一次调用
setTimeout(firstLoadCallback, 50);
// 下面是旧版的监听方式,已经被 observer 取代
// comicList.addEventListener('DOMNodeInserted', (event) => {
//   if (firstLoad && comicListChildren.length > 2) {
//     firstLoad = false;
//     switchParity();
//   }
//   resizeImage(event.target);
//   // event.target.style.height = '100vh';
//   // event.target.style.maxWidth = '100%';
//   // event.target.firstChild.style.setProperty('height', '100%', 'important');
//   // event.target.firstChild.style.setProperty('width', '100%', 'important');
//   // event.target.firstChild.style.objectFit = 'contain';
//   setSingleAlign(comicListChildren.length - 1);
// });
})();