🏠 Home 

Greasy Fork is available in English.

漫画柜双页

漫画柜双页浏览,全屏显示,从右到左显示。


安装此脚本?
  1. // ==UserScript==
  2. // @name 漫画柜双页
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4
  5. // @description 漫画柜双页浏览,全屏显示,从右到左显示。
  6. // @author ChatGPT,akira0245
  7. // @match https://www.manhuagui.com/comic/*/*.html
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=manhuagui.com
  9. // @grant GM_addStyle
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // @license GPLv3
  13. // ==/UserScript==
  14. (function() {
  15. 'use strict';
  16. var pageNum;
  17. var picCount;
  18. var pics;
  19. var picUrls;
  20. var scrollFunction = function(e) {
  21. e = e || window.event;
  22. e.preventDefault && e.preventDefault(); //禁止浏览器默认事件
  23. if (e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件
  24. if (e.wheelDelta > 0) { //当滑轮向上滚动时
  25. onePageUp();
  26. }
  27. if (e.wheelDelta < 0) { //当滑轮向下滚动时
  28. onePageDown();
  29. }
  30. } else if (e.detail) { //Firefox滑轮事件
  31. if (e.detail > 0) { //当滑轮向上滚动时
  32. onePageUp();
  33. }
  34. if (e.detail < 0) { //当滑轮向下滚动时
  35. onePageDown();
  36. }
  37. }
  38. }
  39. //给页面绑定滑轮滚动事件
  40. if (document.addEventListener) { //firefox
  41. document.addEventListener('DOMMouseScroll', scrollFunction, false);
  42. }
  43. //滚动滑轮触发scrollFunction方法 //ie 谷歌
  44. window.addEventListener('mousewheel', scrollFunction, {
  45. passive: false
  46. });
  47. function onePageUp() {
  48. // Find all elements with the data-tag attribute equal to "mangaFile"
  49. var mangaFileElements = document.querySelectorAll('[data-tag="mangaFile"]');
  50. // Find the index of the last mangaFile element that is above the current scroll position
  51. var lastMangaFileIndex = -1;
  52. var currentScrollPosition = window.pageYOffset;
  53. for (var i = mangaFileElements.length - 1; i >= 0; i--) {
  54. if (mangaFileElements[i].getBoundingClientRect().top < 0) {
  55. lastMangaFileIndex = i;
  56. break;
  57. }
  58. }
  59. // If there is a mangaFile element above the current position, scroll to its top position
  60. if (lastMangaFileIndex >= 0) {
  61. var targetElement = mangaFileElements[lastMangaFileIndex];
  62. var targetPosition = targetElement.getBoundingClientRect().top + window.pageYOffset;
  63. window.scrollTo(0, targetPosition);
  64. }else{
  65. window.scrollTo(0, 0);
  66. }
  67. }
  68. function onePageDown() {
  69. // Find all elements with the data-tag attribute equal to "mangaFile"
  70. var mangaFileElements = document.querySelectorAll('[data-tag="mangaFile"]');
  71. // Find the index of the first mangaFile element that is below the current scroll position
  72. var nextMangaFileIndex = -1;
  73. var currentScrollPosition = window.pageYOffset;
  74. for (var i = 0; i < mangaFileElements.length; i++) {
  75. if (mangaFileElements[i].getBoundingClientRect().top > 1) {
  76. nextMangaFileIndex = i;
  77. break;
  78. }
  79. }
  80. // If there is another mangaFile element below the current position, scroll to its top position
  81. if (nextMangaFileIndex >= 0 && nextMangaFileIndex < mangaFileElements.length) {
  82. var targetElement = mangaFileElements[nextMangaFileIndex];
  83. var targetPosition = targetElement.getBoundingClientRect().top + window.pageYOffset;
  84. window.scrollTo(0, targetPosition);
  85. }else{
  86. window.scrollTo(0, document.body.scrollHeight);
  87. }
  88. }
  89. // 绑定事件监听器
  90. document.addEventListener('keydown', function(event) {
  91. switch (event.code) {
  92. // case 'ArrowRight':
  93. // goNumPage('next');
  94. // break;
  95. // case 'ArrowLeft':
  96. // goNumPage('pre');
  97. // break;
  98. // case 'KeyK':
  99. // onePageUp();
  100. // break;
  101. // case 'KeyJ':
  102. // onePageDown();
  103. // break;
  104. // case 'Semicolon':
  105. // switchParity();
  106. // break;
  107. case 'NumpadEnter':
  108. document.querySelector( '.btn-red.nextC').click();
  109. break;
  110. case 'NumpadDecimal':
  111. document.querySelector( '.btn-red.prevC').click();
  112. break;
  113. default:
  114. console.log('key: ' + event.key + ' code: ' + event.code);
  115. }
  116. // event.stopPropagation();
  117. //event.preventDefault && event.preventDefault(); //禁止浏览器默认事件
  118. });
  119. // 获取需要操作的元素
  120. const mangaBox = document.getElementById('mangaBox');
  121. const mangaMoreBox = document.getElementById('mangaMoreBox');
  122. // 获取mangaBox中的元素
  123. const childNodes = mangaBox.childNodes;
  124. // 将mangaBox中的元素插入到mangaMoreBox的第一个位置
  125. mangaMoreBox.insertBefore(childNodes[0], mangaMoreBox.firstChild);
  126. // 删除mangaBox元素
  127. mangaBox.parentNode.removeChild(mangaBox);
  128. if (GM_getValue("MangaPlaceholder")){
  129. togglePlaceHolder();
  130. }
  131. document.addEventListener("mousedown", function(event) {
  132. console.log(event);
  133. const mangaLink = event.target.closest('[data-tag="mangaFile"]');
  134. if (mangaLink) {
  135. event.preventDefault();
  136. if(event.button === 2){
  137. toggleFullScreen();
  138. }
  139. else if (event.button === 0){
  140. togglePlaceHolder();
  141. }
  142. }
  143. });
  144. function togglePlaceHolder() {
  145. let mangaMoreBox = document.getElementById('mangaMoreBox');
  146. let firstChild = mangaMoreBox.firstChild;
  147. var width = firstChild.clientWidth;
  148. var height = firstChild.clientHeight;
  149. let placeholder = document.querySelector(".placeholder");
  150. if (!placeholder) {
  151. GM_setValue("MangaPlaceholder", true);
  152. placeholder = firstChild.cloneNode(true);
  153. placeholder.classList.add("placeholder");
  154. placeholder.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
  155. placeholder.style.width = "66vh";
  156. placeholder.style.height = "100vh";
  157. mangaMoreBox.insertBefore(placeholder, mangaMoreBox.firstChild);
  158. } else {
  159. GM_setValue("MangaPlaceholder", false);
  160. mangaMoreBox.removeChild(placeholder);
  161. }
  162. }
  163. function toggleFullScreen() {
  164. if (!document.fullscreenElement) {
  165. document.documentElement.requestFullscreen();
  166. } else {
  167. if (document.exitFullscreen) {
  168. document.exitFullscreen();
  169. }
  170. }
  171. }
  172. let comicListChildren = mangaMoreBox.children;
  173. function setSingleAlign(imageIndex) {
  174. comicListChildren[imageIndex].style.objectPosition = (imageIndex % 2 == 0) ? 'left' : 'right';
  175. }
  176. function setAlign() {
  177. for (let imageIndex = 0; imageIndex < comicListChildren.length; imageIndex++) {
  178. setSingleAlign(imageIndex);
  179. }
  180. }
  181. function createTitlePage() {
  182. let titlePage = document.createElement('p');
  183. titlePage.textContent = document.title;
  184. titlePage.style.fontSize = 'xx-large';
  185. titlePage.style.maxWidth = '30vw';
  186. titlePage.style.marginTop = '30%';
  187. titlePage.style.marginRight = '20%';
  188. titlePage.style.whiteSpace = 'normal';
  189. return titlePage;
  190. }
  191. let titlePage = createTitlePage();
  192. let parityChanged = false;
  193. function switchParity() {
  194. if (parityChanged) {
  195. comicListChildren[0].remove();
  196. } else {
  197. mangaMoreBox.insertAdjacentElement('afterbegin', titlePage);
  198. }
  199. parityChanged = !parityChanged;
  200. setAlign();
  201. }
  202. // Select the target node for mutation observing
  203. const gridContainer = document.getElementById('mangaMoreBox');
  204. // 创建一个MutationObserver实例,监控DOM变化
  205. var observer = new MutationObserver(function(mutations) {
  206. mutations.forEach(function(mutation) {
  207. if (mutation.addedNodes) {
  208. mutation.addedNodes.forEach(function(node) {
  209. if (node.nodeName === "IMG" && node.getAttribute('data-tag') === 'mangaFile') {
  210. // 创建一个新的Image对象,用于获取图片的原始尺寸
  211. var img = new Image();
  212. img.src = node.src;
  213. // 等待图片加载完成
  214. img.onload = function() {
  215. // 检查图片的长宽比
  216. var aspectRatio = img.width / img.height;
  217. // 如果图片更宽,则将max-width设置为100%
  218. if (aspectRatio > 1) {
  219. node.style.maxWidth = '100%';
  220. }
  221. };
  222. }
  223. });
  224. }
  225. });
  226. });
  227. // 配置MutationObserver以监控子元素的添加
  228. var observerConfig = { childList: true, subtree: true };
  229. // 在整个文档上开始监控
  230. observer.observe(gridContainer, observerConfig);
  231. GM_addStyle(`
  232. #mangaMoreBox {
  233. display: flex;
  234. flex-wrap: wrap;
  235. flex-direction: row-reverse;
  236. justify-content: center;
  237. }
  238. [data-tag="mangaFile"] {
  239. object-fit: contain;
  240. max-width: 50%;
  241. height: 100vh;
  242. }
  243. .img_info {
  244. position: absolute;
  245. display: none;
  246. }
  247. .pr.tbCenter.cb {
  248. all: unset !important;
  249. }
  250. `);
  251. })();