Greasy Fork

Greasy Fork is available in English.

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

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

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

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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.5
// @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, 且请求的地址是获取 reply (TODO: 完善这里!!! (v0.6.3))
            if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseURL.includes('api.bilibili.com/x/v2/reply/')) {
                // 执行
                // 延一下时, 不然有时候不管用, 比如访问: 
                // https://www.bilibili.com/video/BV1SS4y1E7xB?vd_source=1d68bb224288d449a2b448b07dae0cef#reply121876749632
                // 就会出问题.
                setTimeout(() => {
                    removeSearch(changeToItalic);
                    console.log('已干掉新版b站评论区的搜索 (放大镜/蓝字) 功能');
                }, 100);
            }
        });
    });
})();