移除B站顶部搜索框内的占位符

仅移除B站顶部搜索框内的 placeholder 和 title 属性,如果需要移除所有 input 标签的占位符则可以根据下面文档更改回v0.1代码。

// ==UserScript==
// @name         移除B站顶部搜索框内的占位符
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  仅移除B站顶部搜索框内的 placeholder 和 title 属性,如果需要移除所有 input 标签的占位符则可以根据下面文档更改回v0.1代码。
// @author       搞其他
// @match        *://*.bilibili.com/*
// @grant        none
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    function removeAttributes(input) {
        // v0.2修改: 仅移除 nav-search-input 类的 input 的属性
        if (input.classList.contains('nav-search-input')) {
            if (input.hasAttribute('placeholder')) {
                input.removeAttribute('placeholder');
            }
            if (input.hasAttribute('title')) {
                input.removeAttribute('title');
            }
        }
    }

    function observeInput(input) {
        // v0.2修改: 仅观察 nav-search-input 类的 input
        if (input.classList.contains('nav-search-input')) {
            const observer = new MutationObserver(function (mutations) {
                mutations.forEach(function (mutation) {
                    if (mutation.type === 'attributes' && (mutation.attributeName === 'placeholder' || mutation.attributeName === 'title')) {
                        removeAttributes(mutation.target);
                    }
                });
            });

            observer.observe(input, { attributes: true });
        }
    }

    // v0.2修改: 仅选择 nav-search-input 类的 input
    document.querySelectorAll('input.nav-search-input').forEach(function (input) {
        removeAttributes(input);
        observeInput(input);
    });

    const observer = new MutationObserver(function (mutations) {
        mutations.forEach(function (mutation) {
            mutation.addedNodes.forEach(function (node) {
                if (node.nodeType === 1) {
                    // v0.2修改: 仅处理 nav-search-input 类的 input
                    if (node.tagName.toLowerCase() === 'input' && node.classList.contains('nav-search-input')) {
                        removeAttributes(node);
                        observeInput(node);
                    } else {
                        node.querySelectorAll('input.nav-search-input').forEach(function (input) {
                            removeAttributes(input);
                            observeInput(input);
                        });
                    }
                }
            });
        });
    });

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

    function handleIframes() {
        document.querySelectorAll('iframe').forEach(function (iframe) {
            try {
                const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
                // v0.2修改: 仅选择 nav-search-input 类的 input
                iframeDocument.querySelectorAll('input.nav-search-input').forEach(function (input) {
                    removeAttributes(input);
                    observeInput(input);
                });

                const iframeObserver = new MutationObserver(function (mutations) {
                    mutations.forEach(function (mutation) {
                        mutation.addedNodes.forEach(function (node) {
                            if (node.nodeType === 1) {
                                // v0.2修改: 仅处理 nav-search-input 类的 input
                                if (node.tagName.toLowerCase() === 'input' && node.classList.contains('nav-search-input')) {
                                    removeAttributes(node);
                                    observeInput(node);
                                } else {
                                    node.querySelectorAll('input.nav-search-input').forEach(function (input) {
                                        removeAttributes(input);
                                        observeInput(input);
                                    });
                                }
                            }
                        });
                    });
                });

                iframeObserver.observe(iframeDocument.body, { childList: true, subtree: true });
            } catch (e) {
                console.error('error:', e);
            }
        });
    }

    handleIframes();
})();