您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a live word, character, and estimated reading time counter to Bitcointalk reply boxes and posts.
// ==UserScript== // @name Bitcointalk Post & Reply Word/Char Counter // @namespace Royal Cap // @version 1.1.0 // @description Adds a live word, character, and estimated reading time counter to Bitcointalk reply boxes and posts. // @match https://bitcointalk.org/index.php?* // @run-at document-end // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // Counter for textarea (your reply) function createCounterBox(textarea) { if (textarea.dataset.counterAdded) return; textarea.dataset.counterAdded = "1"; const counter = document.createElement('div'); counter.style.fontSize = '12px'; counter.style.marginTop = '4px'; counter.style.color = '#333'; counter.textContent = 'Words: 0 | Characters: 0 | Reading time: 0 min'; textarea.parentNode.insertBefore(counter, textarea.nextSibling); function updateCounter() { const text = textarea.value.trim(); const words = text.length ? text.split(/\s+/).length : 0; const chars = text.length; const readingTime = words ? Math.ceil(words / 200) : 0; // Avg 200 wpm counter.textContent = `Words: ${words} | Characters: ${chars} | Reading time: ${readingTime} min`; } textarea.addEventListener('input', updateCounter); updateCounter(); } // Counter for forum posts (other people's posts) function createPostCounters() { document.querySelectorAll("td.post, div.post").forEach(post => { if (post.dataset.counterAdded) return; post.dataset.counterAdded = "1"; const text = post.innerText.trim(); const words = text.length ? text.split(/\s+/).length : 0; const chars = text.length; const readingTime = words ? Math.ceil(words / 200) : 0; const counter = document.createElement('div'); counter.style.fontSize = '11px'; counter.style.marginTop = '6px'; counter.style.color = 'gray'; counter.style.textAlign = 'right'; counter.textContent = `Words: ${words} | Characters: ${chars} | Reading time: ${readingTime} min`; post.appendChild(counter); }); } function init() { // For reply textarea document.querySelectorAll("textarea[name='message']").forEach(createCounterBox); // For existing posts createPostCounters(); // Watch for dynamic changes const observer = new MutationObserver(() => { document.querySelectorAll("textarea[name='message']").forEach(createCounterBox); createPostCounters(); }); observer.observe(document.body, { childList: true, subtree: true }); } init(); })();