在用户评论区域添加一个 block 按钮,不用点进用户主页,点击即可 block 用户。
// ==UserScript== // @name v2ex 快速屏蔽用户和帖子 // @namespace http://tampermonkey.net/ // @version 0.3 // @description 在用户评论区域添加一个 block 按钮,不用点进用户主页,点击即可 block 用户。 // @author 3989364 // @match *://*.v2ex.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=v2ex.com // @grant none // @license MIT // @note 0.3 实现屏蔽帖子功能 // @note 0.2 扩展 v2ex.com 的域名匹配规则 // ==/UserScript== // TODO: // 1. 帖子外面加个屏蔽用户按钮 // 2. 直接在用户头像链接里面取 userID // 3. 判断用户是否登录,如果没登录直接跳过所有功能 const BASE_URL = window.location.origin; if (!BASE_URL.includes("v2ex.com")) { throw Error("This script only works at v2ex.com, " + BASE_URL); } class OnceCode { /** * onceCode 类似验证码,目测用一次就会失效;目前获取 once code 的方式是请求设置页面提取出 once code */ static async getOnceCode() { const resp = await fetch(`/settings/block`); const text = await resp.text(); const html = document.createElement("html"); html.innerHTML = text; const fn = html .querySelector('input[value="一键清除所有忽略主题"]') .onclick.toString(); return this.parseOnceCode(fn); } static parseOnceCodeURL(text) { return text.match("location.href ?= ?'(.+)'")[1]; } static parseOnceCode(text) { return text.match(/once=(\d+)/)[1]; } } class User { async fetchUserPage(username) { const resp = await fetch(`/member/${username}`); return await resp.text(); } parseBlockURL(page) { const html = document.createElement("html"); html.innerHTML = page; const fn = html.querySelector('input[value="Block"]').onclick; if (fn) { // /block/xxxx?once=19604 return OnceCode.parseOnceCodeURL(fn.toString()); } return null; } async blockUser(username) { const page = await this.fetchUserPage(username); const url = await this.parseBlockURL(page); if (url) { // just dont redirect try { await fetch(url, { redirect: "error", }); } catch {} } } hideUserAllReply(username) { if (!username) { return; } document.querySelectorAll("#Main .cell").forEach((cell) => { const u = cell.querySelector("strong> a")?.textContent; if (u === username) { cell.remove(); } }); } } class Topic { async ignoreTopic(topicId) { const onceCode = await OnceCode.getOnceCode(); try { await fetch(`/ignore/topic/${topicId}?once=${onceCode}`, { redirect: "error", }); } catch {} } } function createBlockButton( text = "block", className = "thank", styleText = "" ) { const blockButton = document.createElement("a"); blockButton.textContent = text; blockButton.className = className; blockButton.style.marginLeft = "0.5rem"; styleText && (blockButton.style = styleText); blockButton.href = "#;"; return blockButton; } function initUserBlockFunction() { function addChildInThankArea(node, thankArea) { thankArea.appendChild(node, thankArea); } const user = new User(); document.querySelectorAll(".thank_area").forEach((thankArea) => { const blockButton = createBlockButton(); addChildInThankArea(blockButton, thankArea); blockButton.addEventListener("click", async function (event) { event.preventDefault(); const wrapper = thankArea.parentNode.parentNode; const username = wrapper.querySelector("strong > a").textContent; if (username && confirm(`确认要屏蔽 ${username} ?`)) { await user.blockUser(username); user.hideUserAllReply(username); } }); }); } function initTopicBlockFunction() { const topic = new Topic(); document .querySelectorAll('#Main .cell.item td[valign="middle"]') .forEach((cell) => { const titleElement = cell.querySelector(".item_title > a"); const infoElement = cell.querySelector(".topic_info"); if (!titleElement) { return; } const topicId = titleElement.href.match(/\/t\/(\d+)/)[1]; const ignoreButton = createBlockButton( "忽略", "title", "color: #ccc; float: right;" ); infoElement.appendChild(ignoreButton); ignoreButton.addEventListener("click", async function () { if (confirm("确定不想再看到这个主题?")) { // debugger await topic.ignoreTopic(topicId); // delete this topic let element = cell.parentElement; const body = document.body; // 向上找到 className = "cell item" 的元素即认为找到了帖子元素 while (element.className !== "cell item" && element !== body) { element = element.parentElement; } if (element !== body) { element.remove(); } else { throw Error("Can't find topic cell"); } } }); }); } (function () { "use strict"; if (location.href.match(/\/t\/\d+/)) { console.log("Init user block function"); initUserBlockFunction(); } initTopicBlockFunction(); })();