Greasy Fork

Greasy Fork is available in English.

干掉新版b站评论区的搜索 (放大镜/蓝字) 功能

干掉新版b站评论区的评论搜索 (放大镜/蓝字) .

当前为 2022-07-21 提交的版本,查看 最新版本

// ==UserScript==
// @name         干掉新版b站评论区的搜索 (放大镜/蓝字) 功能
// @namespace    http://greasyfork.icu/zh-CN/scripts/447612-%E5%B9%B2%E6%8E%89%E6%96%B0%E7%89%88b%E7%AB%99%E8%AF%84%E8%AE%BA%E5%8C%BA%E7%9A%84%E6%90%9C%E7%B4%A2-%E6%94%BE%E5%A4%A7%E9%95%9C-%E8%93%9D%E5%AD%97-%E5%8A%9F%E8%83%BD
// @version      0.6.2
// @description  干掉新版b站评论区的评论搜索 (放大镜/蓝字) .
// @author       DuckBurnIncense
// @match        *://www.bilibili.com/video/*
// @icon         https://www.bilibili.com/favicon.ico
// @homepage     //duckburnincense.ml/
// @supportURL   https://www.bilibili.com/video/BV1SS4y1E7xB
// @license      MIT
// @run-at       document-end
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

// 感谢 @connlost 提供的思路 (hook ajax请求) https://gist.github.com/KrisCris/e615e0c006ee483881011d0513e0a487

// 匿名函数防止b站通过特定变量名屏蔽脚本
(function() {
    // 是否把关键词替换为不可点击的斜体
    // 这个功能主要是给我用的, 比如当有人在评论区说
    // "这个功能还非常的睿智,“全能天使”圈了个“能天使”,“阿米娅”圈了个“米娅”"
    // 我就能知道b站改了没 (无聊罢了)
    // 默认禁用
    const changeToItalic = GM_getValue('changeToItalic', 0);

    // 注册油猴的菜单项
    GM_registerMenuCommand((changeToItalic ? '[✔️已启用]' : '[❌已禁用]') + " 将关键词替换为斜体", function() {
        GM_setValue('changeToItalic', !changeToItalic);
        alert('修改成功, 刷新页面后生效');
    });

    /**
     * 添加 xhr 回调函数
     * @param callback
     */
    // 保存回调的数组
    // 不在 xhr 身上加是因为任何地方都能访问到 XMLHttpRequest,
    // b站可能会通过 xhr 身上的数组来屏蔽脚本.
    // 想过用随机数组名, 然后突然想到 xhr 身上就那么几个永远存在的属性,
    // 直接可以 for in 出来, 就作罢了.
    var callbacks = [];
    const addXHRCallback = callback => {
        // 判断是否已经重写了 xhr
        if(callbacks.length > 0) {
            // 已经重写了 xhr 函数, 加了 callback 功能
            // 直接 push 添加即可
            callbacks.push(callback);
        } else {
            // 没有重写, 在 xhr 上新增一个用来存回调函数的数组
            callbacks = [callback];
            // 保存原来的 send 函数
            const oldSend = XMLHttpRequest.prototype.send;
            // 重写 send 函数
            XMLHttpRequest.prototype.send = function (...data) {
                // this 为 XMLHttpRequest; data 为发往服务器的请求数据
                // 遍历回调数组并调用回调
                callbacks.forEach(cb => {
                    cb(this);
                });
                // 调用原来的 (原生的) send 函数
                oldSend.apply(this, data);
            }
        }
    }

    /**
     * 删除放大镜和把蓝字变回来
     * @param changeToItalic 是否替换为斜体
     */
    const removeSearch = (changeToItalic) => {
        const searchWordsOuterHTMLRegexr = /^(?:<a.*?>)(.*)(?:<\/a>)$/gim;
        // 啊b天天改class名来屏蔽我脚本, 只好改成黑名单模式了
        // 蓝字的类
        const searchWordQueries = [
            'a.jump-url-link.underline-word',
            'a.underline-link.comment-jump-url',
            'a.jump-link.search-word',
        ];
        // 放大镜的类
        const searchIconQueries = [
            'i.jump-url-prefix.search-word',
            'i.underline.jump-img',
            'i.icon.search-word',
        ];
        // 遍历并删除
        searchWordQueries.forEach(query => {
            let searchWords = document.querySelectorAll(query);
            searchWords.forEach(item => {
                item.outerHTML = item.outerHTML.replace(searchWordsOuterHTMLRegexr, changeToItalic ? `<span style="font-style:italic;">$1</span>` : '$1');
            });
        });
        searchIconQueries.forEach(query => {
            let searchIcons = document.querySelectorAll(query);
            searchIcons.forEach(item => {
                item.remove();
            });
        });
    }

    // 添加一个 xhr 回调
    addXHRCallback(xhr => {
        xhr.addEventListener("load", function () {
            // 如果请求完成, 且状态码为 200, 且请求的是 api.bilibili.com/x/v2/reply/main
            if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseURL.includes("api.bilibili.com/x/v2/reply/main")) {
                // 执行
                removeSearch(changeToItalic);
                console.log('已干掉新版b站评论区的搜索 (放大镜/蓝字) 功能');
            }
        });
    });
})();