油猴脚本-🔞多个作用域整合

MarkDown

// ==UserScript==
// @name         🔞多个作用域整合
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  多个作用域整合🔞Extract and Link Movie Code函数模块化🔞查找多个搜索词瀑布流延时排序
// @match        https://javdb.com/*
// @icon         https://javdb.com/favicon-32x32.png
// @grant        GM_xmlhttpRequest
// @require      https://code.jquery.com/jquery-3.6.0.min.js
// ==/UserScript==

(function() {
    'use strict';

    const scriptName = "🔞多个作用域整合🔞Extract and Link Movie Code函数模块化";
    console.log('🟢Script ',scriptName, 'Started🟢');

    //详情页添加跳转链接
    function insertNewLinkAfterSelected() {
         console.log('函数 function insertNewLinkAfterSelected() 开始执行');
        // 选择符合条件的元素
        const element = document.querySelector('a[title="Copy ID"][data-clipboard-text]');

        if (element) {
            // 创建新的 <a> 元素
            const text = element.getAttribute('data-clipboard-text');
            console.log('当前页面番号: ',text); // 输出自定义属性 data-clipboard-text 的值
            const newLink = document.createElement('a');
            newLink.setAttribute('class', 'tag is-info');
            newLink.setAttribute('href', `https://www.javbus.com/${text}`);
            newLink.textContent = 'Go to Bus';
            console.log('创建Go to Bus按钮成功: ',newLink.href);
            // 插入新元素
            element.parentNode.insertBefore(newLink, element.nextSibling);
        } else {
            console.log('未找到符合条件的元素');
        }
        console.log('函数 function insertNewLinkAfterSelected() 执行结束');
    }

    // 调用函数来执行操作
    insertNewLinkAfterSelected();


    function addBlankTargetToLinks() {
        // 获取网页上所有具有href属性的元素
        const elementsWithHref = document.querySelectorAll('[href]');

        // 遍历每个具有href属性的元素
        elementsWithHref.forEach(element => {
            // 添加target="_blank"属性
            element.setAttribute('target', '_blank');
            console.log('为href属性添加新标签页打开属性成功! ');
        });
    }

    // 调用函数以为网页上所有具有href属性的元素添加target="_blank"
    addBlankTargetToLinks();

    function addOpenLinkButtons() {
        console.log('函数 function addOpenLinkButtons() 开始执行');
        // 获取所有的item元素
        const items = document.querySelectorAll('.movie-list .item');
        if (items.length > 0) {
            console.log('Items found:', items);
            // 遍历每个item元素
            items.forEach(item => {
                // 提取链接
                let link = item.querySelector('a.box').getAttribute('href');
                let linkButton = document.createElement('a');
                //linkButton.className = 'tag is-info';
                //linkButton.style.backgroundColor = '#363636';//242424';//#363636';//#2f80ed';//#febe00';//#c00';//#4a4a4a';//#1c1c1c';//#635aee';//#930000';//#ea0080';
                linkButton.setAttribute('class', 'tag is-success');
                linkButton.textContent = 'DB';
                linkButton.setAttribute('href', link);
                linkButton.setAttribute('target', '_blank'); // 在新标签页打开链接
                // 创建按钮
                //const button = document.createElement('button');

                // 按钮点击事件处理程序
                //button.addEventListener('click', () => {
                // 在新标签页打开链接
                //  window.open(link, '_blank');
                //});

                // 将按钮添加到item元素中
                //item.appendChild(button);
                let tagsElement = item.querySelector('.tags');
                if (tagsElement) {
                    tagsElement.appendChild(linkButton);
                    console.log('创建DB按钮成功! ');
                }
            });
        } else {
            console.log('No items found ⭕');
        }
        console.log('函数 function addOpenLinkButtons() 执行结束');
    }

    // 调用函数以添加按钮
    addOpenLinkButtons();

    function addMovieLinks() {
        console.log('函数 function addMovieLinks() 开始执行');
        // 获取所有电影条目
        let movieItems = document.querySelectorAll('.movie-list .item');
        if (movieItems.length > 0) {
            console.log('Items found:', movieItems);
            // 遍历每个电影条目
            movieItems.forEach(function(item) {
                // 获取电影编号信息
                let titleElement = item.querySelector('.video-title');
                if (titleElement) {
                    let movieCode = titleElement.querySelector('strong').textContent.trim();

                    // 创建一个按钮元素
                    let linkButton = document.createElement('a');
                    linkButton.setAttribute('class', 'tag is-link');
                    linkButton.textContent = 'Bus';
                    linkButton.setAttribute('href', `https://www.javbus.com/${movieCode}`);
                    linkButton.setAttribute('target', '_blank'); // 在新标签页打开链接

                    // 将按钮添加到tags区域
                    let tagsElement = item.querySelector('.tags');
                    if (tagsElement) {
                        tagsElement.appendChild(linkButton);
                        console.log('创建Bus按钮成功! ');
                    }
                }
            });
        } else {
            console.log('No items found ⭕');
        }
        console.log('函数 function addMovieLinks() 执行结束');
    }

    // 调用函数以添加电影链接按钮
    addMovieLinks();
    console.log('✅Script ',scriptName, 'Completedd✅');
})();
(function() {
    'use strict';

    const scriptName = "🔞多个作用域整合🔞查找多个搜索词瀑布流延时排序";
    console.log('🟢Script ',scriptName, 'Started🟢');
    // 创建输入框和按钮
    //息子,母,ママ,近親,童貞,王様,親,兄嫁,ガキ,家族,痴,風呂,中出,水泳,射精,風俗,少年,素股,鬼畜,男は僕,ショタ,姉,人妻,交換,誘惑
    //泡泡浴//ソープ
    //按摩//マッサージ
    //小鬼,正太//ガキ,ショタ
    const container = document.createElement('div');
    container.id = 'search-container';
    container.style.margin = '20px';

    const input = document.createElement('input');
    input.type = 'text';
    input.style.backgroundColor = 'black';
    input.style.color= '#AAAAAA';//#3273dc';
    //input.style.fontWeight = 'bold';
    input.style.border = 'none';
    input.id = 'search-input';
    input.value = '息子,母,ママ,近親,童貞,王様,親,兄嫁,ガキ,家族,痴,風呂,中出,水泳,射精,風俗,少年,素股,鬼畜,男は僕,ショタ,姉,人妻,交換,誘惑';
    input.placeholder = '输入内容';

    const searchButton = document.createElement('button');
    searchButton.style.backgroundColor = '#3449a8';
    searchButton.style.color = '#AAAAAA';//#3273dc';
    searchButton.style.cursor = 'Pointer';
    searchButton.id = 'search-button';
    searchButton.textContent = '搜索';

    const clearButton = document.createElement('button');
    clearButton.style.backgroundColor = '#3449a8';
    clearButton.style.color = '#AAAAAA';//#3273dc';
    clearButton.style.cursor = 'Pointer';
    clearButton.id = 'search-button';
    clearButton.textContent = '清空'
    clearButton.addEventListener('click', () => {
        input.value = ''; // 清空输入框的值
    });

    const loadButton = document.createElement('button');
    loadButton.style.backgroundColor= '#3449a8';
    loadButton.style.color= '#AAAAAA';//#3273dc';
    loadButton.style.cursor = 'Pointer';
    loadButton.id = 'load-button';
    loadButton.textContent = '加载'
    loadButton.addEventListener('click', function() {
        // 调用 execute 函数,传入 loadAll 和 resortItems
        execute(loadAll, resortItems, addBlankTargetToLinks);
        //loadAll();
    });

    const resortButton = document.createElement('button');
    resortButton.style.backgroundColor= '#3449a8';
    resortButton.style.color= '#AAAAAA';//#3273dc';
    resortButton.style.cursor = 'Pointer';
    resortButton.id = 'resor-button';
    resortButton.textContent = '排序'
    resortButton.addEventListener('click', function() {
        // 执行主程序逻辑
        resortItems();
    });

    container.appendChild(resortButton)
    container.appendChild(loadButton);
    container.appendChild(input);
    container.appendChild(clearButton);
    container.appendChild(searchButton);
    //const toolbar = document.querySelector("body > section > div > div.toolbar")
    //const toolbar = document.querySelector("body > section > div > div.tabs.main-tabs.is-boxed > ul")
    const toolbar = document.querySelector("#navbar-menu-hero");
    //const toolbar = document.querySelector("#search-bar-container > div > div > div.search-recent-keywords > ul")
    toolbar.appendChild(container);
    //document.body.insertBefore(container, document.body.firstChild);

    searchButton.addEventListener('click', function() {
        const searchTerms = input.value.split(',').map(term => term.trim()); // 获取多个搜索词并去除前后空格
        if (searchTerms.length === 0 || searchTerms.every(term => term === '')) {
            console.log('没有有效的搜索词');
            return;
        }

        const items = document.querySelectorAll('.movie-list .item'); // 选择所有 .item 元素
        // 删除之前的按钮
        const existingButtons = document.querySelectorAll('.tag.is-link');
        existingButtons.forEach(btn => btn.remove());
        /*
        // 标记是否找到匹配的项
        let foundMatch = false;
        */
        // 计数器:跟踪找到的匹配项数量
        let matchCount = 0;

        items.forEach(item => {
            const links = item.querySelectorAll('a'); // 在每个 .item 元素内选择所有 <a> 标签
            links.forEach(link => {
                // 对每个 <a> 标签执行操作
                if (searchTerms.some(term => link.title.includes(term))) { // 检查是否包含任一搜索词
                    console.log("匹配到内容:", link.title);
                    console.log("匹配到item:", item);
                    console.log("匹配到地址:", link.href);

                    let linkButton = document.createElement('a');
                    //linkButton.setAttribute('class', 'tag is-warning');
                    linkButton.setAttribute('class', 'tag is-link');
                    //linkButton.textContent = searchTerms.join(', '); // 显示所有搜索词
                    linkButton.textContent = 'Match';
                    linkButton.setAttribute('href', link.href);
                    linkButton.setAttribute('target', '_blank'); // 在新标签页打开链接

                    // 将按钮添加到 .tags 元素中
                    let tagsElement = item.querySelector('.tags');
                    if (tagsElement) {
                        tagsElement.appendChild(linkButton);
                        console.log('创建关键词按钮成功!');
                    } else {
                        // 如果没有 .tags 元素,可以在 .item 中其他合适的位置插入按钮
                        item.appendChild(linkButton);
                        console.log('创建关键词按钮成功, 添加到 .item!');
                    }
                    // 标记为已找到匹配项
                    //foundMatch = true;
                    // 增加匹配项计数
                    matchCount++;
                } else {
                    // 如果没有找到匹配项
                    console.log('没有匹配到搜索词');
                }
            });
            // 检查是否有链接标题包含任一搜索词
            const hasMatch = Array.from(links).some(link =>
                                                    searchTerms.some(term => link.title.includes(term))
                                                   );

            if (hasMatch) {
                // 如果找到匹配项,标记为已找到
                //foundMatch = true;
            } else {
                // 如果没有找到匹配项,移除该 item 元素
                item.remove();
            }
        });//    items.forEach(item => {结束
        /*// 如果没有找到匹配项,则输出日志
        if (!foundMatch) {
            console.log('没有找到匹配的项');
            alert('没有找到匹配的项');
        }*/
        // 输出匹配项的数量
        if (matchCount > 0) {
            console.log(`找到 ${matchCount} 个匹配的项`);
            alert(`找到 ${matchCount} 个匹配的项`);
        } else {
            console.log('没有找到匹配的项');
            alert('没有找到匹配的项');
        }
        addBlankTargetToLinks();
    });//button.addEventListener('click', function() {结束

    // 调用函数以为网页上所有具有href属性的元素添加target="_blank"
    function addBlankTargetToLinks() {
        // 获取网页上所有具有href属性的元素
        const elementsWithHref = document.querySelectorAll('[href]');

        // 遍历每个具有href属性的元素
        elementsWithHref.forEach(element => {
            // 添加target="_blank"属性
            element.setAttribute('target', '_blank');
            console.log('为href属性添加新标签页打开属性成功! ');
        });
    }// 调用函数以为网页上所有具有href属性的元素添加target="_blank"

    //延时执行函数
    // 主程序逻辑,使用 async/await
    async function execute(func1, func2, func3) {
        try {
            await func1(); // 等待 func1 完成
            func2();// 在 func1 完成后执行 func2
            func3();
        } catch (error) {
            console.error('执行时发生错误:', error);
        }

    }
    //延时执行函数

    //重新排序函数
    function resortItems() {
        // 获取所有 .item 元素
        let items = Array.from(document.querySelectorAll('.movie-list .item'));

        // 排序函数
        items.sort((a, b) => {
            let dateA = new Date(a.querySelector('.meta').textContent.trim());
            let dateB = new Date(b.querySelector('.meta').textContent.trim());
            return dateB - dateA; // 从新到旧排序
        });

        // 重新插入排序后的元素
        let container = document.querySelector('.movie-list'); // 替换为实际容器选择器
        items.forEach(item => container.appendChild(item));
        console.log('重新排序执行完毕');
    }//重新排序函数

    //函数实现瀑布流分页加载,点击按钮时一次性加载分页内容后几页
    function loadAll() {
        return new Promise((resolve, reject) => {
            // 确定容器和项目的选择器
            const containerSelector = '.movie-list'; // 替换为目标容器的选择器

            // 获取当前 URL
            const currentUrl = new URL(window.location.href);

            // 基本 URL(不包括查询参数)
            const baseUrl = currentUrl.origin + currentUrl.pathname;
            const movielist = document.querySelector(containerSelector);
            if (!movielist) {
                console.log('No movielist found ⭕');
                console.log('🛑Script 瀑布流 exiting🛑');
                return reject('No movielist found');
            }

            // 从地址栏提取当前页码
            let currentPage = parseInt(currentUrl.searchParams.get('page')) || 1;

            // 设置最大页数
            const maxPage = currentPage + 9; // 从当前页码开始加载接下来的 9 页

            // 加载当前页码之后的所有内容
            loadAllPages();
            // 加载更多内容函数
            function loadAllPages() {
                // 使用标志位防止重复加载
                if ($('body').data('loading') === true) {
                    return;
                }
                $('body').data('loading', true);

                let pagesLoaded = 0;
                let totalPages = maxPage - currentPage;

                // 存储每个页面加载的 Promise
                const promises = [];

                for (let page = currentPage + 1; page <= maxPage; page++) {
                    const url = `${baseUrl}?page=${page}`;
                    const pagePromise = new Promise((resolvePage, rejectPage) => {
                        GM_xmlhttpRequest({
                            method: 'GET',
                            url: url,
                            onload: function(response) {
                                const newItemsHtml = response.responseText;
                                const newItems = $(newItemsHtml).find(containerSelector).html();
                                $(containerSelector).append(newItems);
                                pagesLoaded++;
                                console.log('页面内容', page, '已加载');
                                resolvePage();
                            },
                            onerror: function(error) {
                                console.error('加载内容失败:', error);
                                rejectPage(error);
                            }
                        });
                    });
                    promises.push(pagePromise);
                }

                // 等待所有页面加载完成
                Promise.all(promises).then(() => {
                    console.log('所有页面内容已加载');
                    $('body').data('loading', false); // 恢复标志位
                    resolve(); // 解析主 Promise
                }).catch(error => {
                    console.error('加载页面失败:', error);
                    $('body').data('loading', false); // 恢复标志位
                    reject(error); // 拒绝主 Promise
                });
            }

        });
    }//函数实现瀑布流分页加载,点击按钮时一次性加载分页内容后几页

    console.log('✅Script ',scriptName, 'Completedd✅');
})();