您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
我不喜欢 IP 属地,但是你手机都显示了,为什么电脑不显示呢?目前仅视频评论区。
当前为
// ==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()