B站隐藏充电和广告

隐藏B站动态瀑布流中的广告、评论区广告、充电内容以及美化首页

// ==UserScript==
// @name         B站隐藏充电和广告
// @version      1.23
// @description  隐藏B站动态瀑布流中的广告、评论区广告、充电内容以及美化首页
// @author       chemhunt
// @match        *.bilibili.com/*
// @match        https://t.bilibili.com/*
// @match        https://space.bilibili.com/*
// @match        https://www.bilibili.com/
// @match        https://www.bilibili.com/video/*
// @namespace    https://gf.qytechs.cn/scripts/511437/
// @grant        GM_registerMenuCommand
// @license      GPL-3.0 License
// ==/UserScript==

/* 更新历史记录
版本1.16:增加UP白名单功能,位于白名单中的UP不再过滤。名单可自行添加。
版本1.17:更新过滤关键词
版本1.18:广告过滤增强
版本1.19:隐藏评论区广告,美化首页
版本1.20:广告过滤增强
版本1.21:修复一个错误
版本1.22:添加白名单设置选项;精简代码,减少性能开销
*/

(function() {
    'use strict';

    // 初始化白名单
    let whiteList = JSON.parse(localStorage.getItem('whiteList')) || [];

    // 添加到白名单
    function addToWhiteList(upId) {
        if (!whiteList.includes(upId)) {
            whiteList.push(upId);
            localStorage.setItem('whiteList', JSON.stringify(whiteList));
            alert(`已将 ${upId} 添加到白名单`);
        } else {
            alert(`${upId} 已在白名单中`);
        }
    }

    // 从白名单中移除
    function removeFromWhiteList(upId) {
        const index = whiteList.indexOf(upId);
        if (index !== -1) {
            whiteList.splice(index, 1);
            localStorage.setItem('whiteList', JSON.stringify(whiteList));
            alert(`已将 ${upId} 从白名单中移除`);
        } else {
            alert(`${upId} 不在白名单中`);
        }
    }

    // 检查是否在白名单中
    function isInWhiteList(upId) {
        return whiteList.includes(upId);
    }

    // 显示白名单管理菜单
    function WhiteListMenu() {
        const adContainer = document.createElement('div');
        adContainer.id = 'kimiAdContainer';
        adContainer.style.cssText = `
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 500px;
        padding: 20px;
        background: #fff;
        border: 1px solid #ccc;
        border-radius: 10px;
        z-index: 10000;
        font-size: 16px;
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    `;

        const Title = document.createElement('h4');
        Title.textContent = `手动管理白名单`;
        Title.style.cssText = 'text-align: center; margin-bottom: 20px;';
        adContainer.appendChild(Title);

        // 添加UP部分
        const addUpRow = document.createElement('div');
        addUpRow.style.cssText = 'display: flex; align-items: center; margin-bottom: 10px;';
        const addUpLabel = document.createElement('label');
        addUpLabel.textContent = '添加UP的ID:';
        addUpLabel.style.marginRight = '10px';
        addUpRow.appendChild(addUpLabel);

        const addUpInput = document.createElement('input');
        addUpInput.type = 'text';
        addUpInput.id = 'kimiaddUp';
        addUpInput.placeholder = '请输入UP的ID';
        addUpInput.style.flex = '1';
        addUpRow.appendChild(addUpInput);

        const saveButton = document.createElement('button');
        saveButton.textContent = '增加';
        saveButton.style.marginLeft = '10px';
        saveButton.addEventListener('click', () => {
            const upId = addUpInput.value.trim();
            if (upId) {
                addToWhiteList(upId);
                //document.body.removeChild(adContainer);
            }
        });
        addUpRow.appendChild(saveButton);
        adContainer.appendChild(addUpRow);

        // 删除UP部分
        const removeUpRow = document.createElement('div');
        removeUpRow.style.cssText = 'display: flex; align-items: center; margin-bottom: 10px;';
        const removeUpLabel = document.createElement('label');
        removeUpLabel.textContent = '删除UP的ID:';
        removeUpLabel.style.marginRight = '10px';
        removeUpRow.appendChild(removeUpLabel);

        const removeUpInput = document.createElement('input');
        removeUpInput.type = 'text';
        removeUpInput.id = 'kimiremoveUp';
        removeUpInput.placeholder = '请输入UP的ID';
        removeUpInput.style.flex = '1';
        removeUpRow.appendChild(removeUpInput);

        const deleteButton = document.createElement('button');
        deleteButton.textContent = '删除';
        deleteButton.style.marginLeft = '10px';
        deleteButton.addEventListener('click', () => {
            const upId = removeUpInput.value.trim();
            if (upId) {
                removeFromWhiteList(upId);
            }
        });
        removeUpRow.appendChild(deleteButton);
        adContainer.appendChild(removeUpRow);

        // 显示白名单列表和完成按钮的容器
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = `    display: flex;    justify-content: center;    gap: 10px;    margin-top: 20px;`;

        // 显示白名单列表按钮
        const showListButton = document.createElement('button');
        showListButton.textContent = '显示白名单列表';
        showListButton.style.cssText = 'padding: 5px 10px;';
        showListButton.addEventListener('click', () => {
            const listDisplay = document.getElementById('whiteListDisplay');
            if (listDisplay) {
                adContainer.removeChild(listDisplay);
            } else {
                const listDiv = document.createElement('div');
                listDiv.id = 'whiteListDisplay';
                listDiv.textContent = whiteList.join(', ');
                listDiv.style.cssText = ` text-align: center; color: #555; margin-top: 10px; font-size: 14px; word-break: break-word;`;
                buttonContainer.insertAdjacentElement('afterend', listDiv);
            }
        });
        buttonContainer.appendChild(showListButton);

        // 完成按钮
        const finishButton = document.createElement('button');
        finishButton.textContent = '完成';
        finishButton.style.cssText = 'padding: 5px 10px;';
        finishButton.addEventListener('click', () => {
            document.body.removeChild(adContainer);
        });
        buttonContainer.appendChild(finishButton);
        adContainer.appendChild(buttonContainer);
        document.body.appendChild(adContainer);
    }

    // 注册(不可用)菜单命令
    GM_registerMenuCommand("UP白名单", WhiteListMenu);

    const messageDiv = document.createElement('div');
    Object.assign(messageDiv.style, {
        position: 'fixed',
        top: '10px',
        right: '10px',
        padding: '10px',
        backgroundColor: 'rgba(0, 0, 0, 0.7)',
        color: 'white',
        borderRadius: '5px',
        zIndex: '9999',
        display: 'none'
    });

    document.body.appendChild(messageDiv);

    const blockedKeywords = [
        '拼多多', '淘宝', '京东', '天猫', '手淘', '旗舰店','运费',
        '特价', '领券', '下单', '礼包', '补贴', '优惠', '双11','双12', '618', '品牌方',
        '溪木源', '海力生', '萌牙家', '妙界', '神气小鹿', 'DAWEI', '温眠', '护肝', '护颈','护眼', '护枕', '按摩', '冲牙','牙刷','流量卡',
        //'中奖', '预告', '抽奖',
    ];

    const blockedLinks = [
         'taobao.com','tb.cn', 'jd.com', 'pinduoduo.com', 'mall.bilibili.com', 'gaoneng.bilibili.com', 'yangkeduo.com', 'zhuanzhuan.com', 'firegz.com', '52haoka.com','aiyo-aiyo.com', 'bilibili.com/cheese/'
    ];

    function hideItem(item) {
        item.style.display = 'none';
    }

    function showMessage(msg) {
        messageDiv.textContent = msg;
        messageDiv.style.display = 'block';
        setTimeout(() => {
            messageDiv.style.display = 'none';
        }, 3000);
    }

    // 检查评论区广告
    function checkCommentTopAds() {
        const commentAds = document.querySelectorAll('.dynamic-card-comment .comment-list.has-limit .list-item.reply-wrap.is-top');
        commentAds.forEach(comment => {
            const links = comment.querySelectorAll('a');
            links.forEach(link => {
                const href = link.getAttribute('href');
                if (href && blockedLinks.some(blocked => href.includes(blocked))) {
                    hideItem(comment);
                    return 1;
                }
            });
        });
        return 0;
    }

    let hiddenAdCount = 0;

    function checkCommentsForAds() {
        const commentsContainer = document.querySelector('#commentapp > bili-comments');
        if (commentsContainer && commentsContainer.shadowRoot) {
            const headerElement = commentsContainer.shadowRoot.querySelector("#header > bili-comments-header-renderer");
            if (headerElement && headerElement.shadowRoot) {
                const noticeElement = headerElement.shadowRoot.querySelector("#notice > bili-comments-notice");
                if (noticeElement && noticeElement.shadowRoot) {
                    const closeElement = noticeElement.shadowRoot.querySelector("#close");
                    if (closeElement) {
                        console.log("找到评论区横条,自动点击关闭按钮");
                        closeElement.click();
                    }
                }

                const thread = commentsContainer.shadowRoot.querySelector('bili-comment-thread-renderer');
                if (thread && window.getComputedStyle(thread).display !== 'none' && thread.shadowRoot) {
                    const commentRenderer = thread.shadowRoot.querySelector('#comment');
                    if (commentRenderer && commentRenderer.shadowRoot) {
                        const richText = commentRenderer.shadowRoot.querySelector('#content > bili-rich-text');
                        if (richText && richText.shadowRoot) {
                            const contentsElement = richText.shadowRoot.querySelector('#contents');
                            if (contentsElement) {
                                let foundAd = false;
                                const links = contentsElement.querySelectorAll('a');
                                links.forEach(link => {
                                    const href = link.getAttribute('href');
                                    if (href && blockedLinks.some(blocked => href.includes(blocked))) {
                                        foundAd = true;
                                    }
                                });

                                if (foundAd) {
                                    console.log('发现评论区广告');
                                    hideItem(thread);
                                    hiddenAdCount++;
                                    observer.disconnect();
                                    let message = `隐藏广告 x ${hiddenAdCount}`;
                                    showMessage(message);
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
            return false;
        }
    }

    function checkForContentToHide() {
        let hiddenChargeCount = 0;
        let hiddenAdCount = 0;

        if (window.location.hostname === 't.bilibili.com' || window.location.hostname === 'space.bilibili.com') {
            if (window.location.hostname === 't.bilibili.com') {
                hiddenAdCount += checkCommentTopAds();
            }
            const items = document.querySelectorAll('.bili-dyn-list__item');
            items.forEach(item => {
                const titleElement = item.querySelector('.bili-dyn-title');
                if (titleElement && whiteList.includes(titleElement.textContent.trim())) {
                    return;
                }
                const ask = item.querySelector('.dyn-icon-badge__renderimg.bili-dyn-item__iconbadge');
                const blockedmask = item.querySelector('.dyn-blocked-mask');
                const badge = item.querySelector('.bili-dyn-card-video__badge');
                const lotteryTitle = item.querySelector('.dyn-upower-lottery__title');
                const contentDiv = item.querySelector('.bili-dyn-content');
                const goods = item.querySelector('dyn-goods');
                const goods2 = item.querySelector('bili-dyn-card-goods');
                const spans = item.querySelectorAll('span');

                if (window.getComputedStyle(item).display !== 'none') {
                    if (goods || goods2) {
                        hideItem(item);
                        hiddenAdCount++;
                    } else if (blockedmask || ask ||
                               (badge && badge.textContent.includes('专属') ||
                                Array.from(spans).some(span => span.textContent.includes('专属')) ||
                                (lotteryTitle && lotteryTitle.textContent.includes('专属')))
                              ) {
                        hideItem(item);
                        hiddenChargeCount++;
                    } else if (contentDiv) {
                        const contentText = contentDiv.textContent;
                        if (blockedKeywords.some(keyword => contentText.includes(keyword))) {
                            hideItem(item);
                            hiddenAdCount++;
                        }
                    }
                }
                if (window.getComputedStyle(item).display !== 'none') {
                    spans.forEach(span => {
                        const dataUrl = span.getAttribute('data-url');
                        if (dataUrl && blockedLinks.some(blocked => dataUrl.includes(blocked))) {
                            hideItem(item);
                            hiddenAdCount++;
                        }
                    });
                }
            });
        }

        if (window.location.hostname === 'www.bilibili.com' && !window.location.pathname.startsWith('/video/')) {
            const floorCards = document.querySelectorAll('.floor-single-card');
            floorCards.forEach(card => {
                if (window.getComputedStyle(card).display !== 'none'){
                    hideItem(card);
                }
                //hiddenFloorCardCount++;
            });

            const targetElement = document.querySelector('.recommended-swipe.grid-anchor');
            if (targetElement && window.getComputedStyle(targetElement).display !== 'none') {
                console.log('隐藏首页大屏');
                hideItem(targetElement);
            }
        }

        if (window.location.pathname.startsWith('/video/')) {
            if (!checkCommentsForAds()) {
                setTimeout(() => {
                    checkCommentsForAds();
                }, 2000);
            }
            const targetElement = document.querySelector('.bili-mini-mask');
            const popElement = document.querySelector('.v-popover');
            if (targetElement && window.getComputedStyle(targetElement).display !== 'none') {
                console.log('隐藏登录(不可用)');
                hideItem(targetElement);
            }
        }

        let message = '';
        if (hiddenChargeCount > 0) {
            message += `隐藏充电 x ${hiddenChargeCount} `;
        }
        if (hiddenAdCount > 0) {
            message += `隐藏广告 x ${hiddenAdCount} `;
        }
        if (message) {
            showMessage(message.trim());
        }
    }


    function debounce(func, wait) {
        let timeout;
        return function(...args) {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    }

    // 创建 MutationObserver
    //const target = document.querySelector('.bili-dyn-list__items');

    function initObserver() {
        const observer = new MutationObserver(debounce(checkForContentToHide, 250));
        observer.observe(document.body,{ childList: true, subtree: true, attributes: true, attributeFilter: ['class'] });
        return observer;
    }

    // 初始启动观察器
    console.log('脚本加载,初始化observer');
    const observer = initObserver();
    window.observer = observer;


    // 重新启动观察器
    function restartObserver() {
        console.log('页面内容更新,重新启动observer');
        if (window.observer) {
            window.observer.disconnect();
        }
        const observer = initObserver();
        window.observer = observer;
    }

    // 监听 commentapp 元素的变化
    function initCommentAppObserver() {
        const commentAppElement = document.querySelector('#commentapp');
        if (commentAppElement) {
            const commentAppObserver = new MutationObserver(restartObserver);
            commentAppObserver.observe(commentAppElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['class']});
            console.log('启动commentapp 元素observer');
        }
    }

    initCommentAppObserver();
    //*/
})();

QingJ © 2025

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