漫画柜双页

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

// ==UserScript==
// @name         漫画柜双页
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  漫画柜双页浏览,全屏显示,从右到左显示。
// @author       ChatGPT,akira0245
// @match        https://www.manhuagui.com/comic/*/*.html
// @icon         https://www.google.com/s2/favicons?sz=64&domain=manhuagui.com
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @license      GPLv3
// ==/UserScript==


(function() {
    'use strict';

    var pageNum;
    var picCount;
    var pics;
    var picUrls;

    var scrollFunction = function(e) {
        e = e || window.event;
        e.preventDefault && e.preventDefault(); //禁止浏览器默认事件
        if (e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件
            if (e.wheelDelta > 0) { //当滑轮向上滚动时
                onePageUp();
            }
            if (e.wheelDelta < 0) { //当滑轮向下滚动时
                onePageDown();
            }

        } else if (e.detail) { //Firefox滑轮事件
            if (e.detail > 0) { //当滑轮向上滚动时
                onePageUp();
            }
            if (e.detail < 0) { //当滑轮向下滚动时
                onePageDown();
            }
        }
    }
    //给页面绑定滑轮滚动事件
    if (document.addEventListener) { //firefox
        document.addEventListener('DOMMouseScroll', scrollFunction, false);
    }
    //滚动滑轮触发scrollFunction方法  //ie 谷歌
    window.addEventListener('mousewheel', scrollFunction, {
        passive: false
    });


    function onePageUp() {
        // Find all elements with the data-tag attribute equal to "mangaFile"
        var mangaFileElements = document.querySelectorAll('[data-tag="mangaFile"]');

        // Find the index of the last mangaFile element that is above the current scroll position
        var lastMangaFileIndex = -1;
        var currentScrollPosition = window.pageYOffset;
        for (var i = mangaFileElements.length - 1; i >= 0; i--) {
            if (mangaFileElements[i].getBoundingClientRect().top < 0) {
                lastMangaFileIndex = i;
                break;
            }
        }

        // If there is a mangaFile element above the current position, scroll to its top position
        if (lastMangaFileIndex >= 0) {
            var targetElement = mangaFileElements[lastMangaFileIndex];
            var targetPosition = targetElement.getBoundingClientRect().top + window.pageYOffset;
            window.scrollTo(0, targetPosition);
        }else{
            window.scrollTo(0, 0);
        }
    }

    function onePageDown() {
        // Find all elements with the data-tag attribute equal to "mangaFile"
        var mangaFileElements = document.querySelectorAll('[data-tag="mangaFile"]');

        // Find the index of the first mangaFile element that is below the current scroll position
        var nextMangaFileIndex = -1;
        var currentScrollPosition = window.pageYOffset;
        for (var i = 0; i < mangaFileElements.length; i++) {
            if (mangaFileElements[i].getBoundingClientRect().top > 1) {
                nextMangaFileIndex = i;
                break;
            }
        }

        // If there is another mangaFile element below the current position, scroll to its top position
        if (nextMangaFileIndex >= 0 && nextMangaFileIndex < mangaFileElements.length) {
            var targetElement = mangaFileElements[nextMangaFileIndex];
            var targetPosition = targetElement.getBoundingClientRect().top + window.pageYOffset;
            window.scrollTo(0, targetPosition);
        }else{
            window.scrollTo(0, document.body.scrollHeight);
        }
    }



    // 绑定事件监听器
    document.addEventListener('keydown', function(event) {
        switch (event.code) {
                // case 'ArrowRight':
                //     goNumPage('next');
                //     break;
                // case 'ArrowLeft':
                //     goNumPage('pre');
                //     break;
                // case 'KeyK':
                //     onePageUp();
                //     break;
                // case 'KeyJ':
                //     onePageDown();
                //     break;
                // case 'Semicolon':
                //     switchParity();
                //     break;
            case 'NumpadEnter':
                document.querySelector( '.btn-red.nextC').click();
                break;
            case 'NumpadDecimal':
                document.querySelector( '.btn-red.prevC').click();
                break;
            default:
                console.log('key: ' + event.key + ' code: ' + event.code);
        }
        // event.stopPropagation();
        //event.preventDefault && event.preventDefault(); //禁止浏览器默认事件
    });



    // 获取需要操作的元素
    const mangaBox = document.getElementById('mangaBox');
    const mangaMoreBox = document.getElementById('mangaMoreBox');

    // 获取mangaBox中的元素
    const childNodes = mangaBox.childNodes;

    // 将mangaBox中的元素插入到mangaMoreBox的第一个位置
    mangaMoreBox.insertBefore(childNodes[0], mangaMoreBox.firstChild);

    // 删除mangaBox元素
    mangaBox.parentNode.removeChild(mangaBox);

    if (GM_getValue("MangaPlaceholder")){
        togglePlaceHolder();
    }

    document.addEventListener("mousedown", function(event) {
        console.log(event);
        const mangaLink = event.target.closest('[data-tag="mangaFile"]');
        if (mangaLink) {
            event.preventDefault();
            if(event.button === 2){
                toggleFullScreen();
            }
            else if (event.button === 0){
                togglePlaceHolder();
            }
        }
    });

    function togglePlaceHolder() {
        let mangaMoreBox = document.getElementById('mangaMoreBox');
        let firstChild = mangaMoreBox.firstChild;
        var width = firstChild.clientWidth;
        var height = firstChild.clientHeight;
        let placeholder = document.querySelector(".placeholder");
        if (!placeholder) {
            GM_setValue("MangaPlaceholder", true);
            placeholder = firstChild.cloneNode(true);
            placeholder.classList.add("placeholder");
            placeholder.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
            placeholder.style.width = "66vh";
            placeholder.style.height = "100vh";
            mangaMoreBox.insertBefore(placeholder, mangaMoreBox.firstChild);
        } else {
            GM_setValue("MangaPlaceholder", false);
            mangaMoreBox.removeChild(placeholder);
        }
    }

    function toggleFullScreen() {
        if (!document.fullscreenElement) {
            document.documentElement.requestFullscreen();
        } else {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            }
        }
    }

    let comicListChildren = mangaMoreBox.children;

    function setSingleAlign(imageIndex) {
        comicListChildren[imageIndex].style.objectPosition = (imageIndex % 2 == 0) ? 'left' : 'right';
    }

    function setAlign() {
        for (let imageIndex = 0; imageIndex < comicListChildren.length; imageIndex++) {
            setSingleAlign(imageIndex);
        }
    }


    function createTitlePage() {
        let titlePage = document.createElement('p');
        titlePage.textContent = document.title;
        titlePage.style.fontSize = 'xx-large';
        titlePage.style.maxWidth = '30vw';
        titlePage.style.marginTop = '30%';
        titlePage.style.marginRight = '20%';
        titlePage.style.whiteSpace = 'normal';
        return titlePage;
    }

    let titlePage = createTitlePage();

    let parityChanged = false;

    function switchParity() {
        if (parityChanged) {
            comicListChildren[0].remove();
        } else {
            mangaMoreBox.insertAdjacentElement('afterbegin', titlePage);
        }
        parityChanged = !parityChanged;
        setAlign();
    }


    // Select the target node for mutation observing
    const gridContainer = document.getElementById('mangaMoreBox');

    // 创建一个MutationObserver实例,监控DOM变化
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.addedNodes) {
                mutation.addedNodes.forEach(function(node) {
                    if (node.nodeName === "IMG" && node.getAttribute('data-tag') === 'mangaFile') {
                        // 创建一个新的Image对象,用于获取图片的原始尺寸
                        var img = new Image();
                        img.src = node.src;

                        // 等待图片加载完成
                        img.onload = function() {
                            // 检查图片的长宽比
                            var aspectRatio = img.width / img.height;

                            // 如果图片更宽,则将max-width设置为100%
                            if (aspectRatio > 1) {
                                node.style.maxWidth = '100%';
                            }
                        };
                    }
                });
            }
        });
    });

    // 配置MutationObserver以监控子元素的添加
    var observerConfig = { childList: true, subtree: true };

    // 在整个文档上开始监控
    observer.observe(gridContainer, observerConfig);

    GM_addStyle(`

    #mangaMoreBox {
    display: flex;
    flex-wrap: wrap;
    flex-direction: row-reverse;
    justify-content: center;
    }
    [data-tag="mangaFile"] {
    object-fit: contain;
        max-width: 50%;
        height: 100vh;
    }
    .img_info {
        position: absolute;
        display: none;
    }
    .pr.tbCenter.cb {
        all: unset !important;
    }
`);




})();