Jutsu +

Наведитесь на кнопку серии чтобы посмотреть названия и кадр, Автоматический пропуст интро и переключение на следующий эпизод

当前为 2025-05-23 提交的版本,查看 最新版本

// ==UserScript==
// @name         Jutsu +
// @namespace    by
// @version      1.1
// @author       diorhc
// @description  Наведитесь на кнопку серии чтобы посмотреть названия и кадр, Автоматический пропуст интро и переключение на следующий эпизод
// @description:en  Hover over the series button to see the titles and frame - auto skip, intro and switch to the next episode on Jut.su
// @match        https://jut.su/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=jut.su
// @license      MIT
// @grant        none
// ==/UserScript==
(function() {
    'use strict';

    // Add stylesheet once DOM is ready
    function addStyles() {
        const style = document.createElement("style");
        style.innerHTML = `
            #prevbox {
                margin-top: 55px;
                margin-left: -163px;
                display: none;
                width: 200px;
                height: auto;
                position: absolute;
                z-index: 9999;
                opacity: 0;
                transition: all 0.2s ease 0s;
                box-shadow: 0 0 15px black;
                border-radius: 5px;
                border: 2px solid rgba(102, 107, 102, 0.8);
                text-align: center;
            }
            #prevbox > div {
                border-radius: 0 0 5px 5px;
                top: 10px;
                padding: 3px 14px;
                background-color: #363a37;
                min-height: max-content;
                border-top: 1px solid #505550;
            }
            #prevbox::before, #prevbox::after {
                content: "" !important;
                display: inline-block;
                position: absolute;
                margin-top: -10px;
                top: 5px;
                height: 10px;
                width: 10px;
                border-radius: 100%;
                border: 1px solid #666b66;
                background-color: #363a37;
            }
            #prevbox::before {
                left: -5px;
            }
            #prevbox::after {
                right: -5px;
            }
            #prevbox > img {
                background: url(https://i.imgur.com/DLLjUig.png) center no-repeat rgb(54, 58, 55);
                width: 200px;
                height: 112.5px;
            }`;
        document.head.appendChild(style);
    }

    // Preview functionality
    function setupPreviewBoxes() {
        const currentPath = window.location.pathname;
        const linkElements = document.querySelectorAll(
            `#dle-content > div > div:nth-child(2) > a[href*='${currentPath}']`
        );

        linkElements.forEach(linkElement => {
            createPreviewBox(linkElement);
        });
    }

    function createPreviewBox(linkElement) {
        let prevbox = document.createElement("div");
        prevbox.id = "prevbox";
        
        const imgElement = document.createElement("img");
        const nameBox = document.createElement("div");
        const nameElement = document.createElement("text");
        
        nameBox.appendChild(nameElement);
        prevbox.appendChild(imgElement);
        prevbox.appendChild(nameBox);
        
        let loaded = loadFromCache();
        
        // Hover event handlers
        let showTimer = null;
        let fadeTimer = null;
        
        linkElement.addEventListener("mouseenter", handleMouseEnter);
        linkElement.addEventListener("mouseleave", handleMouseLeave);
        linkElement.insertAdjacentElement("afterend", prevbox);
        
        function loadFromCache() {
            if (localStorage[linkElement.href] && localStorage[linkElement.href + "name"]) {
                imgElement.src = localStorage[linkElement.href];
                nameElement.innerText = localStorage[linkElement.href + "name"];
                return true;
            }
            return false;
        }
        
        function handleMouseEnter() {
            clearTimeout(showTimer);
            clearTimeout(fadeTimer);
            
            showTimer = setTimeout(() => {
                if (!loaded) {
                    loadPreviewContent();
                }
                prevbox.style.opacity = "0";
                prevbox.style.display = "block";
                
                fadeTimer = setTimeout(() => {
                    prevbox.style.opacity = "1";
                }, 100);
            }, 200);
        }
        
        function handleMouseLeave() {
            clearTimeout(showTimer);
            clearTimeout(fadeTimer);
            prevbox.style.opacity = "0";
            
            setTimeout(() => {
                prevbox.style.display = "none";
            }, 200);
        }
        
        function loadPreviewContent() {
            fetch(linkElement.href)
                .then(response => {
                    if (!response.ok) throw new Error('Network response was not ok');
                    return response.arrayBuffer();
                })
                .then(buffer => {
                    let html = new TextDecoder("windows-1251").decode(buffer);
                    const parser = new DOMParser();
                    const doc = parser.parseFromString(html, 'text/html');
                    
                    const imgUrl = doc.querySelector('meta[property="og:image"]')?.content;
                    const nameText = doc.querySelector('#dle-content div.video_plate_title h2')?.innerHTML;
                    
                    if (imgUrl && nameText) {
                        nameElement.innerText = nameText;
                        imgElement.src = imgUrl;
                        
                        localStorage[linkElement.href + "name"] = nameText;
                        localStorage[linkElement.href] = imgUrl;
                        loaded = true;
                    }
                })
                .catch(error => {
                    console.error("Error loading preview:", error);
                });
        }
    }

    // Auto-skip and auto-next functionality
    function setupVideoControls() {
        // Observer for skip intro and next episode buttons
        const observer = new MutationObserver(() => {
            clickIfVisible('.vjs-overlay-skip-intro:not(.vjs-hidden)');
            clickIfVisible('.vjs-overlay-bottom-right.vjs-overlay-skip-intro:not(.vjs-hidden)');
        });

        observer.observe(document.body, { childList: true, subtree: true });

        // Auto-navigate to next episode when video ends
        const video = document.querySelector("video");
        if (video) {
            video.addEventListener("ended", () => {
                const nextEpisodeButton = document.querySelector(".vnright a");
                if (nextEpisodeButton && nextEpisodeButton.href) {
                    window.location.href = nextEpisodeButton.href;
                }
            });
        }
    }

    function clickIfVisible(selector) {
        const element = document.querySelector(selector);
        if (element) {
            element.click();
        }
    }

    // Initialize everything when DOM is ready
    function init() {
        addStyles();
        setupPreviewBoxes();
        setupVideoControls();
    }

    // Wait for DOM to be ready before initializing
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        setTimeout(init, 1000); // Give the page a moment to fully render
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址