字数限制新规出台,是否配套增加字数统计提示

2026-04-11 11:081阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

字数限制新规出台,是否可以配套增加字数统计提示,原先 6 字还是很容易肉眼计数的,现在限制 20 字经常遇到:字数不足 → 增加几个字 → 字数不足 的尴尬情况,如果有个字数提示器就方便多了

image730×286 10.2 KB

油猴简单实现了一下,不过还是希望有个官方提示器哈哈

字数统计提示器

// ==UserScript== // @name Linux.do 字数统计显示 // @namespace https://linux.do/ // @version 1.0 // @description 在 Linux.do 论坛帖子编辑区右下角显示实时字数统计 // @match https://linux.do/* // @grant none // ==/UserScript== (function () { 'use strict'; /** * 等待某个元素出现 * @param {string} selector * @param {number} timeout 毫秒 * @returns {Promise<HTMLElement>} */ function waitForElement(selector, timeout = 20000) { return new Promise((resolve) => { const el = document.querySelector(selector); if (el) return resolve(el); const observer = new MutationObserver(() => { const element = document.querySelector(selector); if (element) { observer.disconnect(); resolve(element); } }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(() => { observer.disconnect(); }, timeout); }); } /** * 创建字数统计显示容器 */ function createCounter() { const counter = document.createElement('div'); counter.id = 'post-word-counter'; counter.style.position = 'absolute'; counter.style.right = '8px'; counter.style.bottom = '4px'; counter.style.fontSize = '13px'; counter.style.color = '#888'; counter.style.userSelect = 'none'; counter.style.pointerEvents = 'none'; counter.style.zIndex = '10'; return counter; } /** * 初始化字数统计 */ async function initCounter() { const textarea = await waitForElement('.d-editor-input'); if (!textarea) return; // 防止重复添加 if (document.querySelector('#post-word-counter')) return; const wrapper = textarea.closest('.d-editor-textarea-wrapper'); if (!wrapper) return; const counter = createCounter(); wrapper.style.position = 'relative'; wrapper.appendChild(counter); const updateCount = () => { const text = textarea.value.trim(); const length = text.length; counter.textContent = `字数:${length}`; }; textarea.addEventListener('input', updateCount); updateCount(); } /** * 监听编辑器打开事件(Discourse 动态加载) */ function observeComposer() { const observer = new MutationObserver(() => { const composer = document.querySelector('.d-editor-input'); if (composer && !document.querySelector('#post-word-counter')) { initCounter(); } }); observer.observe(document.body, { childList: true, subtree: true }); } // 启动监听 observeComposer(); })();

v1.1 增加红绿高亮优化,灵感来自 @torvalds

// ==UserScript== // @name Linux.do 字数统计 + 剩余提示 // @namespace https://linux.do/ // @version 1.1 // @description 在 Linux.do 编辑器右下角显示实时字数统计,不足20字符警示 // @match https://linux.do/* // @grant none // ==/UserScript== (function () { 'use strict'; // ✅ 等待元素出现工具函数 function waitForElement(selector, timeout = 20000) { return new Promise((resolve) => { const el = document.querySelector(selector); if (el) return resolve(el); const observer = new MutationObserver(() => { const element = document.querySelector(selector); if (element) { observer.disconnect(); resolve(element); } }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(() => observer.disconnect(), timeout); }); } // ✅ 创建计数器元素 function createCounter() { const counter = document.createElement('div'); counter.id = 'post-word-counter'; counter.style.position = 'absolute'; counter.style.right = '8px'; counter.style.bottom = '8px'; counter.style.fontSize = '13px'; counter.style.color = '#fff'; counter.style.padding = '2px 10px'; counter.style.borderRadius = '12px'; counter.style.userSelect = 'none'; counter.style.pointerEvents = 'none'; counter.style.zIndex = '10'; counter.style.backgroundColor = '#444'; // 默认灰色 counter.style.transition = 'all 0.2s'; return counter; } async function initCounter() { const textarea = await waitForElement('.d-editor-input'); if (!textarea) return; // 避免重复 if (document.querySelector('#post-word-counter')) return; const wrapper = textarea.closest('.d-editor-textarea-wrapper'); if (!wrapper) return; const counter = createCounter(); wrapper.style.position = 'relative'; wrapper.appendChild(counter); const updateCount = () => { const text = textarea.value.trim(); const length = text.length; const minRequired = 20; const remaining = minRequired - length; if (length < minRequired) { counter.textContent = `字数:${length} | 还差 ${remaining} 个字符`; counter.style.backgroundColor = '#b71c1c'; // 红色 } else { counter.textContent = `字数:${length}`; counter.style.backgroundColor = '#2e7d32'; // 绿色 } }; textarea.addEventListener('input', updateCount); updateCount(); } // ✅ 监听编辑器出现(Discourse 动态) function observeComposer() { const observer = new MutationObserver(() => { const composer = document.querySelector('.d-editor-input'); if (composer && !document.querySelector('#post-word-counter')) { initCounter(); } }); observer.observe(document.body, { childList: true, subtree: true }); } observeComposer(); })();

v1.2 修复中文输入法拼音误统计bug

// ==UserScript== // @name Linux.do 字数统计(中文输入优化) // @namespace https://linux.do/ // @version 1.2 // @description 在 Linux.do 编辑器右下角显示实时字数统计,支持中文输入法候选状态,不足20字符红色提示 // @match https://linux.do/* // @grant none // ==/UserScript== (function () { 'use strict'; // 等待元素出现 function waitForElement(selector, timeout = 20000) { return new Promise((resolve) => { const el = document.querySelector(selector); if (el) return resolve(el); const observer = new MutationObserver(() => { const element = document.querySelector(selector); if (element) { observer.disconnect(); resolve(element); } }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(() => observer.disconnect(), timeout); }); } // 创建计数器 function createCounter() { const counter = document.createElement('div'); counter.id = 'post-word-counter'; counter.style.position = 'absolute'; counter.style.right = '8px'; counter.style.bottom = '8px'; counter.style.fontSize = '13px'; counter.style.color = '#fff'; counter.style.padding = '2px 10px'; counter.style.borderRadius = '12px'; counter.style.userSelect = 'none'; counter.style.pointerEvents = 'none'; counter.style.zIndex = '10'; counter.style.backgroundColor = '#444'; // 默认灰色 counter.style.transition = 'all 0.2s'; return counter; } async function initCounter() { const textarea = await waitForElement('.d-editor-input'); if (!textarea) return; if (document.querySelector('#post-word-counter')) return; const wrapper = textarea.closest('.d-editor-textarea-wrapper'); if (!wrapper) return; const counter = createCounter(); wrapper.style.position = 'relative'; wrapper.appendChild(counter); let isComposing = false; // 是否处于中文输入法拼音阶段 const updateCount = () => { if (isComposing) return; // 忽略拼音输入过程 const text = textarea.value.trim(); const len = text.length; const min = 20; const remaining = min - len; if (len < min) { counter.textContent = `字数:${len} | 还差 ${remaining} 个字符`; counter.style.backgroundColor = '#b71c1c'; // 红色 } else { counter.textContent = `字数:${len}`; counter.style.backgroundColor = '#2e7d32'; // 绿色 } }; textarea.addEventListener('compositionstart', () => { isComposing = true; }); textarea.addEventListener('compositionend', () => { isComposing = false; updateCount(); // 中文确认后更新 }); textarea.addEventListener('input', updateCount); updateCount(); } // 监听 Discourse 编辑器加载 function observeComposer() { const observer = new MutationObserver(() => { const composer = document.querySelector('.d-editor-input'); if (composer && !document.querySelector('#post-word-counter')) { initCounter(); } }); observer.observe(document.body, { childList: true, subtree: true }); } observeComposer(); })();

网友解答:
--【壹】--:

今天已经被举报好多次了,看看别人都是怎么弄的


--【贰】--:

image755×415 22.9 KB


--【叁】--:

加了其他md字符吧,比如星号加粗加了很多这种


--【肆】--:

为啥你一个字就可以
我十分疑惑你这个表述方案


--【伍】--: Pierre Zhang:

************可************

这种强行凑字数的方案倒是第一次见,各位佬友各显神通,就是容易陨落


--【陆】--:

我觉得可以啊 不让还得自己去测试 打了多少字数了


--【柒】--:
别看

说别看,你又看了是吧

还可以在折叠块里面放垃圾文字(折叠内容一般没人看),在外面放正常的简短的回复


--【捌】--:

八仙过海各显神通,我是服了你了哈哈哈,太狠了。


--【玖】--:

这样是不行的哦,一举报一个准的呢。。还是要足字数


--【拾】--:

感谢佬的脚本,有个字数统计对于回复来说真的很方便


--【拾壹】--:

小心因为发现始皇留下的特性被始皇请进去喝茶


--【拾贰】--:

为啥要加字数限制,只会添加更多无意义内容,加上数据存储压力


--【拾叁】--:

Linus Torvalds 还是太快了


--【拾肆】--:

泻药,已陨落。(7字)

自从我按下“回复”键的那一刻起,那条评论的最终归宿就确定了。(37字)


--【拾伍】--:

添加不渲染的标记?比如这样?

#可 <div/> <div/> <div/> <div/> <div/> <div/> <div/> <div/> <div/> <div/>

出来就是这样:


--【拾陆】--:

这个字数限制让我今天被举报好几次了。难受


--【拾柒】--: Pierre Zhang:

泻药,已陨落。(7 字)

自从我按下 “回复” 键的那一刻起,那条评论的最终归宿就确定了。(37 字)

参考这位佬。
论坛的管理员都是手工审核的,这种过得了AI 过不了人眼,而且只是扫一眼的事


--【拾捌】--:

确实好用
小瑕疵就是 打拼音中途 没按空格之前出现的字母 也算了字数。


--【拾玖】--:

这楼是不是已经被不可名状和谐掉看不见了

问题描述:

字数限制新规出台,是否可以配套增加字数统计提示,原先 6 字还是很容易肉眼计数的,现在限制 20 字经常遇到:字数不足 → 增加几个字 → 字数不足 的尴尬情况,如果有个字数提示器就方便多了

image730×286 10.2 KB

油猴简单实现了一下,不过还是希望有个官方提示器哈哈

字数统计提示器

// ==UserScript== // @name Linux.do 字数统计显示 // @namespace https://linux.do/ // @version 1.0 // @description 在 Linux.do 论坛帖子编辑区右下角显示实时字数统计 // @match https://linux.do/* // @grant none // ==/UserScript== (function () { 'use strict'; /** * 等待某个元素出现 * @param {string} selector * @param {number} timeout 毫秒 * @returns {Promise<HTMLElement>} */ function waitForElement(selector, timeout = 20000) { return new Promise((resolve) => { const el = document.querySelector(selector); if (el) return resolve(el); const observer = new MutationObserver(() => { const element = document.querySelector(selector); if (element) { observer.disconnect(); resolve(element); } }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(() => { observer.disconnect(); }, timeout); }); } /** * 创建字数统计显示容器 */ function createCounter() { const counter = document.createElement('div'); counter.id = 'post-word-counter'; counter.style.position = 'absolute'; counter.style.right = '8px'; counter.style.bottom = '4px'; counter.style.fontSize = '13px'; counter.style.color = '#888'; counter.style.userSelect = 'none'; counter.style.pointerEvents = 'none'; counter.style.zIndex = '10'; return counter; } /** * 初始化字数统计 */ async function initCounter() { const textarea = await waitForElement('.d-editor-input'); if (!textarea) return; // 防止重复添加 if (document.querySelector('#post-word-counter')) return; const wrapper = textarea.closest('.d-editor-textarea-wrapper'); if (!wrapper) return; const counter = createCounter(); wrapper.style.position = 'relative'; wrapper.appendChild(counter); const updateCount = () => { const text = textarea.value.trim(); const length = text.length; counter.textContent = `字数:${length}`; }; textarea.addEventListener('input', updateCount); updateCount(); } /** * 监听编辑器打开事件(Discourse 动态加载) */ function observeComposer() { const observer = new MutationObserver(() => { const composer = document.querySelector('.d-editor-input'); if (composer && !document.querySelector('#post-word-counter')) { initCounter(); } }); observer.observe(document.body, { childList: true, subtree: true }); } // 启动监听 observeComposer(); })();

v1.1 增加红绿高亮优化,灵感来自 @torvalds

// ==UserScript== // @name Linux.do 字数统计 + 剩余提示 // @namespace https://linux.do/ // @version 1.1 // @description 在 Linux.do 编辑器右下角显示实时字数统计,不足20字符警示 // @match https://linux.do/* // @grant none // ==/UserScript== (function () { 'use strict'; // ✅ 等待元素出现工具函数 function waitForElement(selector, timeout = 20000) { return new Promise((resolve) => { const el = document.querySelector(selector); if (el) return resolve(el); const observer = new MutationObserver(() => { const element = document.querySelector(selector); if (element) { observer.disconnect(); resolve(element); } }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(() => observer.disconnect(), timeout); }); } // ✅ 创建计数器元素 function createCounter() { const counter = document.createElement('div'); counter.id = 'post-word-counter'; counter.style.position = 'absolute'; counter.style.right = '8px'; counter.style.bottom = '8px'; counter.style.fontSize = '13px'; counter.style.color = '#fff'; counter.style.padding = '2px 10px'; counter.style.borderRadius = '12px'; counter.style.userSelect = 'none'; counter.style.pointerEvents = 'none'; counter.style.zIndex = '10'; counter.style.backgroundColor = '#444'; // 默认灰色 counter.style.transition = 'all 0.2s'; return counter; } async function initCounter() { const textarea = await waitForElement('.d-editor-input'); if (!textarea) return; // 避免重复 if (document.querySelector('#post-word-counter')) return; const wrapper = textarea.closest('.d-editor-textarea-wrapper'); if (!wrapper) return; const counter = createCounter(); wrapper.style.position = 'relative'; wrapper.appendChild(counter); const updateCount = () => { const text = textarea.value.trim(); const length = text.length; const minRequired = 20; const remaining = minRequired - length; if (length < minRequired) { counter.textContent = `字数:${length} | 还差 ${remaining} 个字符`; counter.style.backgroundColor = '#b71c1c'; // 红色 } else { counter.textContent = `字数:${length}`; counter.style.backgroundColor = '#2e7d32'; // 绿色 } }; textarea.addEventListener('input', updateCount); updateCount(); } // ✅ 监听编辑器出现(Discourse 动态) function observeComposer() { const observer = new MutationObserver(() => { const composer = document.querySelector('.d-editor-input'); if (composer && !document.querySelector('#post-word-counter')) { initCounter(); } }); observer.observe(document.body, { childList: true, subtree: true }); } observeComposer(); })();

v1.2 修复中文输入法拼音误统计bug

// ==UserScript== // @name Linux.do 字数统计(中文输入优化) // @namespace https://linux.do/ // @version 1.2 // @description 在 Linux.do 编辑器右下角显示实时字数统计,支持中文输入法候选状态,不足20字符红色提示 // @match https://linux.do/* // @grant none // ==/UserScript== (function () { 'use strict'; // 等待元素出现 function waitForElement(selector, timeout = 20000) { return new Promise((resolve) => { const el = document.querySelector(selector); if (el) return resolve(el); const observer = new MutationObserver(() => { const element = document.querySelector(selector); if (element) { observer.disconnect(); resolve(element); } }); observer.observe(document.body, { childList: true, subtree: true }); setTimeout(() => observer.disconnect(), timeout); }); } // 创建计数器 function createCounter() { const counter = document.createElement('div'); counter.id = 'post-word-counter'; counter.style.position = 'absolute'; counter.style.right = '8px'; counter.style.bottom = '8px'; counter.style.fontSize = '13px'; counter.style.color = '#fff'; counter.style.padding = '2px 10px'; counter.style.borderRadius = '12px'; counter.style.userSelect = 'none'; counter.style.pointerEvents = 'none'; counter.style.zIndex = '10'; counter.style.backgroundColor = '#444'; // 默认灰色 counter.style.transition = 'all 0.2s'; return counter; } async function initCounter() { const textarea = await waitForElement('.d-editor-input'); if (!textarea) return; if (document.querySelector('#post-word-counter')) return; const wrapper = textarea.closest('.d-editor-textarea-wrapper'); if (!wrapper) return; const counter = createCounter(); wrapper.style.position = 'relative'; wrapper.appendChild(counter); let isComposing = false; // 是否处于中文输入法拼音阶段 const updateCount = () => { if (isComposing) return; // 忽略拼音输入过程 const text = textarea.value.trim(); const len = text.length; const min = 20; const remaining = min - len; if (len < min) { counter.textContent = `字数:${len} | 还差 ${remaining} 个字符`; counter.style.backgroundColor = '#b71c1c'; // 红色 } else { counter.textContent = `字数:${len}`; counter.style.backgroundColor = '#2e7d32'; // 绿色 } }; textarea.addEventListener('compositionstart', () => { isComposing = true; }); textarea.addEventListener('compositionend', () => { isComposing = false; updateCount(); // 中文确认后更新 }); textarea.addEventListener('input', updateCount); updateCount(); } // 监听 Discourse 编辑器加载 function observeComposer() { const observer = new MutationObserver(() => { const composer = document.querySelector('.d-editor-input'); if (composer && !document.querySelector('#post-word-counter')) { initCounter(); } }); observer.observe(document.body, { childList: true, subtree: true }); } observeComposer(); })();

网友解答:
--【壹】--:

今天已经被举报好多次了,看看别人都是怎么弄的


--【贰】--:

image755×415 22.9 KB


--【叁】--:

加了其他md字符吧,比如星号加粗加了很多这种


--【肆】--:

为啥你一个字就可以
我十分疑惑你这个表述方案


--【伍】--: Pierre Zhang:

************可************

这种强行凑字数的方案倒是第一次见,各位佬友各显神通,就是容易陨落


--【陆】--:

我觉得可以啊 不让还得自己去测试 打了多少字数了


--【柒】--:
别看

说别看,你又看了是吧

还可以在折叠块里面放垃圾文字(折叠内容一般没人看),在外面放正常的简短的回复


--【捌】--:

八仙过海各显神通,我是服了你了哈哈哈,太狠了。


--【玖】--:

这样是不行的哦,一举报一个准的呢。。还是要足字数


--【拾】--:

感谢佬的脚本,有个字数统计对于回复来说真的很方便


--【拾壹】--:

小心因为发现始皇留下的特性被始皇请进去喝茶


--【拾贰】--:

为啥要加字数限制,只会添加更多无意义内容,加上数据存储压力


--【拾叁】--:

Linus Torvalds 还是太快了


--【拾肆】--:

泻药,已陨落。(7字)

自从我按下“回复”键的那一刻起,那条评论的最终归宿就确定了。(37字)


--【拾伍】--:

添加不渲染的标记?比如这样?

#可 <div/> <div/> <div/> <div/> <div/> <div/> <div/> <div/> <div/> <div/>

出来就是这样:


--【拾陆】--:

这个字数限制让我今天被举报好几次了。难受


--【拾柒】--: Pierre Zhang:

泻药,已陨落。(7 字)

自从我按下 “回复” 键的那一刻起,那条评论的最终归宿就确定了。(37 字)

参考这位佬。
论坛的管理员都是手工审核的,这种过得了AI 过不了人眼,而且只是扫一眼的事


--【拾捌】--:

确实好用
小瑕疵就是 打拼音中途 没按空格之前出现的字母 也算了字数。


--【拾玖】--:

这楼是不是已经被不可名状和谐掉看不见了