哔哩哔哩网页版展示 IP 属地

我不喜欢 IP 属地,但是你手机都显示了,为什么电脑不显示呢?目前仅视频评论区。

目前為 2023-05-22 提交的版本,檢視 最新版本

// ==UserScript==
// @name         哔哩哔哩网页版展示 IP 属地
// @namespace    http://zhangmaimai.com
// @version      0.2
// @description  我不喜欢 IP 属地,但是你手机都显示了,为什么电脑不显示呢?目前仅视频评论区。
// @author       You
// @match        https://www.bilibili.com/video/*
// @match        https://www.bilibili.com/medialist/play/*
// @match        https://www.bilibili.com/bangumi/play/*
// @icon         https://www.bilibili.com/favicon.ico
// @grant        none
// @run-at       document-body
// @license    MIT
// ==/UserScript==

/**
 * @param {HTMLDivElement} replyItemEl 
 * @return {string}
 */
const getIPAddress = (replyItemEl) => {
    const IPString = (
        replyItemEl.className.startsWith("sub")
            ? replyItemEl.querySelector('.reply-content')
            : replyItemEl
    )?.__vnode?.ctx?.props?.reply?.reply_control?.location
    return IPString ? `${IPString}  ` : ""
}

/**
 * @param {HTMLDivElement} replyItemEl 
 */
const createIPAddressEl = (replyItemEl) => {
    const IPAddressEl = document.createElement('span')
    IPAddressEl.className = "reply-time"
    IPAddressEl.innerHTML = getIPAddress(replyItemEl)
    return IPAddressEl
}

/** @param {HTMLDivElement} replyItemEl */
const injectIPAddressEl = (replyItemEl) => {
    /** @type {HTMLDivElement} */
    const replyInfo = replyItemEl.className.startsWith("sub")
        ? replyItemEl.querySelector('.sub-reply-info')
        : replyItemEl.querySelector('.reply-info')
    replyInfo.insertAdjacentElement('afterbegin', createIPAddressEl(replyItemEl))
}

/**
 * @param {string} selector 
 * @returns {Promise<HTMLDivElement>}
 */
const isElementLoaded = async (selector) => {
    while (document.querySelector(selector) === null) {
        await new Promise(resolve => requestAnimationFrame(resolve))
    }
    return document.querySelector(selector)
}

const setupObserver = async () => {

    const targetNode = await isElementLoaded('.reply-list')

    /** @type {MutationObserverInit} */
    const config = { attributes: true, childList: true, subtree: true }

    /** 
     * @param {MutationRecord[]} mutationsList 
     * @param {MutationObserver} observer 
     */
    const callback = (mutationsList, observer) => {
        for (let mutation of mutationsList) {
            if (mutation.type !== 'childList') continue
            /** @param {HTMLElement} el */
            const isReplyItem = (el) => (el instanceof HTMLDivElement) && ([
                "reply-item",
                "sub-reply-item"
            ].includes(el.className))
            for (let node of mutation.addedNodes) {
                if (!(isReplyItem(node))) continue
                injectIPAddressEl(node)
                if (node.className.startsWith("sub")) continue
                /** @type {HTMLDivElement[]} */
                const subReplyList = Array.from(node.querySelector('.sub-reply-list').children)
                subReplyList.pop()
                for (let subReply of subReplyList) {
                    injectIPAddressEl(subReply)
                }
            }
        }
    }

    const observer = new MutationObserver(callback)

    observer.observe(targetNode, config)
}

setupObserver()

QingJ © 2025

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