Greasy Fork镜像 还支持 简体中文。

小红书首页简洁模式

在小红书首页添加模式切换功能,支持原生模式和简洁模式切换。简洁模式在首页移除其余元素仅显示搜索框。

// ==UserScript==
// @name         小红书首页简洁模式
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  在小红书首页添加模式切换功能,支持原生模式和简洁模式切换。简洁模式在首页移除其余元素仅显示搜索框。
// @author       kamaboko
// @match        https://www.xiaohongshu.com/explore*
// @match        https://www.xiaohongshu.com/explore/*
// @license      GPL-3.0 License
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 等待页面加载完成
    function waitForElement(selector, timeout = 10000) {
        return new Promise((resolve, reject) => {
            const element = document.querySelector(selector);
            if (element) {
                resolve(element);
                return;
            }

            const observer = new MutationObserver((mutations, obs) => {
                const element = document.querySelector(selector);
                if (element) {
                    obs.disconnect();
                    resolve(element);
                }
            });

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

            setTimeout(() => {
                observer.disconnect();
                reject(new Error(`Element ${selector} not found within ${timeout}ms`));
            }, timeout);
        });
    }

    // 创建模式切换按钮
    function createModeToggleButton() {
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 10000;
            background: #fff;
            border: 2px solid #ff2442;
            border-radius: 8px;
            padding: 8px 12px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        `;

        const button = document.createElement('button');
        button.textContent = '原生模式';
        button.style.cssText = `
            background: #ff2442;
            color: white;
            border: none;
            border-radius: 4px;
            padding: 6px 12px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: all 0.2s ease;
        `;

        button.addEventListener('mouseenter', () => {
            button.style.background = '#e61e3c';
        });

        button.addEventListener('mouseleave', () => {
            button.style.background = '#ff2442';
        });

        buttonContainer.appendChild(button);
        document.body.appendChild(buttonContainer);

        return { button, container: buttonContainer };
    }

    // 获取需要隐藏的元素选择器
    function getElementsToHide() {
        return [
            // 导航栏相关
            'nav',
            '.nav',
            '.navbar',
            '.header',
            '.top-bar',
            // 侧边栏
            '.side-bar',
            '.side-nav',
            '.dropdown-nav',
            '.left-panel',
            // 推荐内容区域
            '.recommend',
            '.feed',
            '.content-feed',
            '.explore-feed',
            // 其他可能的内容区域
            '.main-content:not(.search-container)',
            '.content-area:not(.search-container)',
            // 底部
            '.footer',
            '.bottom-nav'
        ];
    }

    // 隐藏/显示元素
    function toggleElements(hide, elementsToHide) {
        elementsToHide.forEach(selector => {
            const elements = document.querySelectorAll(selector);
            elements.forEach(element => {
                if (hide) {
                    element.style.display = 'none';
                } else {
                    element.style.display = '';
                }
            });
        });
    }

    // 查找并保留搜索框
    function preserveSearchBox() {
        // 为mask-paper类添加样式,让它在屏幕中间显示
        const maskPaperElements = document.querySelectorAll('.mask-paper');
        maskPaperElements.forEach(element => {
            element.style.cssText = `
                position: fixed !important;
                top: 50% !important;
                left: 50% !important;
                transform: translate(-50%, -50%) !important;
                z-index: 9999 !important;
                display: flex !important;
                flex-direction: column !important;
                align-items: center !important;
                gap: 10px !important;
                width: auto !important;
                height: auto !important;
            `;
        });

        // 为logo图标添加样式,让它显示在上方
        const logoElements = document.querySelectorAll('.header-logo');
        logoElements.forEach(element => {
            element.style.cssText = `
                width: 120px !important;
                height: auto !important;
                pointer-events: none !important;
                order: -1 !important;
            `;
        });

        // 为搜索框容器添加样式,确保它在下方且居中
        const inputBoxElements = document.querySelectorAll('.input-box');
        inputBoxElements.forEach(element => {
            element.style.cssText = `
                display: flex !important;
                align-items: center !important;
                justify-content: center !important;
                width: auto !important;
                height: auto !important;
                order: 1 !important;
                position: relative !important;
                min-height: 50px !important;
            `;
        });

        // 为搜索框添加样式
        const searchInputElements = document.querySelectorAll('.search-input');
        searchInputElements.forEach(element => {
            if (element.tagName === 'INPUT' && element.type === 'text') {
                element.style.cssText = `
                    width: 500px !important;
                    height: 50px !important;
                    border-radius: 25px !important;
                    padding: 0 20px !important;
                    outline: none !important;
                `;
            }
        });

        // 为搜索按钮添加样式,确保它在搜索框中且生效
        const inputButtonElements = document.querySelectorAll('.input-button');
        inputButtonElements.forEach(element => {
            element.style.cssText = `
                position: absolute !important;
                right: 10px !important;
                top: 50% !important;
                transform: translateY(-50%) !important;
                z-index: 10000 !important;
                pointer-events: auto !important;
                cursor: pointer !important;
            `;
        });

        // 修复下拉菜单的位置,确保它在搜索框下方显示且保持原样
        const dropdownElements = document.querySelectorAll('[class*="sug-pad"], [class*="suggestion"], [class*="autocomplete"]');
        dropdownElements.forEach(element => {
            element.style.cssText = `
                position: absolute !important;
                top: 100% !important;
                left: 0 !important;
                width: 100% !important;
                z-index: 10001 !important;
                transform: none !important;
            `;
        });

        // 特别处理sug-pad sug-container-wrapper类的下拉菜单
        const sugPadElements = document.querySelectorAll('.sug-container-wrapper.sug-pad');
        sugPadElements.forEach(element => {
            element.style.cssText = `
                position: absolute !important;
                top: 100% !important;
                left: 0 !important;
                width: 100% !important;
                z-index: 10001 !important;
                transform: none !important;
                margin-top: 5px !important;
            `;
        });

        // 创建MutationObserver来监听下拉菜单的动态创建
        const dropdownObserver = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                if (mutation.type === 'childList') {
                    mutation.addedNodes.forEach((node) => {
                        if (node.nodeType === Node.ELEMENT_NODE) {
                            // 检查新添加的元素是否是下拉菜单
                            if (node.classList && (node.classList.contains('sug-pad') || node.classList.contains('sug-container-wrapper'))) {
                                applyDropdownStyles(node);
                            }
                            // 检查新添加元素的子元素
                            const dropdowns = node.querySelectorAll('[class*="sug-pad"], [class*="sug-container-wrapper"]');
                            dropdowns.forEach(dropdown => applyDropdownStyles(dropdown));
                        }
                    });
                }
            });
        });

        // 应用下拉菜单样式的函数
        function applyDropdownStyles(element) {
            element.style.setProperty('position', 'absolute', 'important');
            element.style.setProperty('top', '100%', 'important');
            element.style.setProperty('left', '0', 'important');
            element.style.setProperty('width', '100%', 'important');
            element.style.setProperty('z-index', '10001', 'important');
            element.style.setProperty('transform', 'none', 'important');
            element.style.setProperty('margin-top', '5px', 'important');
        }

        // 开始监听DOM变化
        dropdownObserver.observe(document.body, {
            childList: true,
            subtree: true
        });

        // 将observer保存到全局,以便在恢复时停止监听
        window.xiaohongshuDropdownObserver = dropdownObserver;
    }

    // 恢复搜索框原始样式的函数
    function restoreSearchBoxOriginalStyle() {
        // 恢复mask-paper的原始样式
        const maskPaperElements = document.querySelectorAll('.mask-paper');
        maskPaperElements.forEach(element => {
            element.style.cssText = '';
        });

        // 恢复logo的原始样式
        const logoElements = document.querySelectorAll('.header-logo');
        logoElements.forEach(element => {
            element.style.cssText = '';
        });

        // 恢复搜索框的原始样式
        const searchInputElements = document.querySelectorAll('.search-input');
        searchInputElements.forEach(element => {
            if (element.tagName === 'INPUT' && element.type === 'text') {
                element.style.cssText = '';
            }
        });

        // 恢复input-box的原始样式
        const inputBoxElements = document.querySelectorAll('.input-box');
        inputBoxElements.forEach(element => {
            element.style.cssText = '';
        });

        // 恢复input-button的原始样式
        const inputButtonElements = document.querySelectorAll('.input-button');
        inputButtonElements.forEach(element => {
            element.style.cssText = '';
        });

        // 恢复下拉菜单的原始样式
        const dropdownElements = document.querySelectorAll('[class*="sug-pad"], [class*="suggestion"], [class*="autocomplete"]');
        dropdownElements.forEach(element => {
            element.style.cssText = '';
        });

        // 特别恢复sug-pad sug-container-wrapper类的下拉菜单
        const sugPadElements = document.querySelectorAll('.sug-container-wrapper.sug-pad');
        sugPadElements.forEach(element => {
            element.style.cssText = '';
        });

        // 停止下拉菜单的MutationObserver监听
        if (window.xiaohongshuDropdownObserver) {
            window.xiaohongshuDropdownObserver.disconnect();
            window.xiaohongshuDropdownObserver = null;
        }
    }

    // 主函数
    async function init() {
        try {
            // 等待页面主要内容加载
            await waitForElement('body');

            // 创建模式切换按钮
            const { button, container } = createModeToggleButton();

            let isNativeMode = true;
            const elementsToHide = getElementsToHide();

            // 检查当前URL,如果不是explore页面,自动恢复到原生模式
            function checkAndRestoreMode() {
                const currentUrl = window.location.href;
                if (!currentUrl.includes('/explore')) {
                    // 不在explore页面,自动恢复到原生模式
                    isNativeMode = true;
                    button.textContent = '原生模式';
                    button.style.background = '#ff2442';
                    toggleElements(false, elementsToHide);

                    // 恢复搜索框原始位置
                    const searchElements = document.querySelectorAll('input[type="search"], input[placeholder*="搜索"], .search-input');
                    searchElements.forEach(element => {
                        const container = element.closest('.search-container') || element.closest('form') || element.parentElement;
                        if (container) {
                            container.style.cssText = '';
                        }
                    });

                    // 恢复input-box的原始位置
                    const inputBoxElements = document.querySelectorAll('.input-box');
                    inputBoxElements.forEach(element => {
                        element.style.cssText = '';
                    });

                    // 恢复搜索框、logo等的原始样式
                    restoreSearchBoxOriginalStyle();
                } else {
                    // 在explore页面,检查是否是分享链接
                    const urlParams = new URLSearchParams(window.location.search);
                    const isShareLink = urlParams.has('share_from_user_hidden') ||
                                       urlParams.has('share_id') ||
                                       urlParams.has('xsec_source') ||
                                       urlParams.has('type') ||
                                       urlParams.has('author_share') ||
                                       urlParams.has('xhsshare');

                    if (isShareLink) {
                        // 分享链接保持原生模式
                        isNativeMode = true;
                        button.textContent = '原生模式';
                        button.style.background = '#ff2442';
                        toggleElements(false, elementsToHide);
                        restoreSearchBoxOriginalStyle();
                        localStorage.setItem('xiaohongshuMode', 'original');
                    } else {
                        // 普通explore页面,检查用户偏好设置
                        const userPreference = localStorage.getItem('xiaohongshuMode');
                        if (userPreference === 'minimal' || userPreference === null) {
                            // 默认使用简洁模式,或者用户之前选择过简洁模式
                            isNativeMode = false;
                            button.textContent = '简洁模式';
                            button.style.background = '#28a745';
                            toggleElements(true, elementsToHide);
                            preserveSearchBox();
                            localStorage.setItem('xiaohongshuMode', 'minimal');
                        }
                    }
                }
            }

            // 添加点击事件
            button.addEventListener('click', () => {
                // 检查是否在explore页面
                if (!window.location.href.includes('/explore')) {
                    alert('此功能仅在首页可用');
                    return;
                }

                // 检查是否是分享链接
                const urlParams = new URLSearchParams(window.location.search);
                const isShareLink = urlParams.has('share_from_user_hidden') ||
                                   urlParams.has('share_id') ||
                                   urlParams.has('xsec_source') ||
                                   urlParams.has('type') ||
                                   urlParams.has('author_share') ||
                                   urlParams.has('xhsshare');

                if (isShareLink) {
                    alert('分享链接页面不支持模式切换,将保持原生模式');
                    return;
                }

                isNativeMode = !isNativeMode;

                if (isNativeMode) {
                    button.textContent = '原生模式';
                    button.style.background = '#ff2442';
                    toggleElements(false, elementsToHide);
                    // 恢复搜索框原始位置
                    const searchElements = document.querySelectorAll('input[type="search"], input[placeholder*="搜索"], .search-input');
                    searchElements.forEach(element => {
                        const container = element.closest('.search-container') || element.closest('form') || element.parentElement;
                        if (container) {
                            container.style.cssText = '';
                        }
                    });

                    // 恢复input-box的原始位置
                    const inputBoxElements = document.querySelectorAll('.input-box');
                    inputBoxElements.forEach(element => {
                        element.style.cssText = '';
                    });

                    // 恢复搜索框、logo等的原始样式
                    restoreSearchBoxOriginalStyle();

                    // 保存用户偏好
                    localStorage.setItem('xiaohongshuMode', 'original');
                } else {
                    button.textContent = '简洁模式';
                    button.style.background = '#28a745';
                    toggleElements(true, elementsToHide);
                    preserveSearchBox();

                    // 保存用户偏好
                    localStorage.setItem('xiaohongshuMode', 'minimal');
                }
            });

            // 监听URL变化
            let currentUrl = window.location.href;
            const urlObserver = new MutationObserver(() => {
                if (window.location.href !== currentUrl) {
                    currentUrl = window.location.href;
                    checkAndRestoreMode();
                }
            });

            // 监听页面内容变化(包括pushState等)
            urlObserver.observe(document.body, {
                childList: true,
                subtree: true
            });

            // 监听popstate事件(浏览器前进后退)
            window.addEventListener('popstate', checkAndRestoreMode);

            // 重写pushState和replaceState方法以监听URL变化
            const originalPushState = history.pushState;
            const originalReplaceState = history.replaceState;

            history.pushState = function(...args) {
                originalPushState.apply(this, args);
                setTimeout(checkAndRestoreMode, 100);
            };

            history.replaceState = function(...args) {
                originalReplaceState.apply(this, args);
                setTimeout(checkAndRestoreMode, 100);
            };

            // 初始化时检查并应用模式
            checkAndRestoreMode();
        } catch (error) {
            console.error('加载失败:', error);
        }
    }

    // 页面加载完成后初始化
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();

QingJ © 2025

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