惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
有赞技术团队
有赞技术团队
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
爱范儿
爱范儿
Vercel News
Vercel News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Y
Y Combinator Blog
Blog — PlanetScale
Blog — PlanetScale
D
DataBreaches.Net
美团技术团队
Microsoft Security Blog
Microsoft Security Blog
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
GbyAI
GbyAI
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
The Cloudflare Blog
宝玉的分享
宝玉的分享
V
V2EX
Microsoft Azure Blog
Microsoft Azure Blog

秋記Autumn - 秋記Autumn

再过30年,一个时代会彻底结束 - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 老大毕业相册片选 - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 假如让你回到18岁,你愿意吗? - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 给博客导航条天气小插件,整了一套手绘图标 - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 又是一年开学季 - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 一位普通家长的心声,请把课堂还给孩子,把夜晚还给家庭 - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 自己写了一款Typecho友链RSS聚合插件 - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 暑假预制娃,谁在推着跑! - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 秋季养生新技巧 - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 一串桃核盘了六年 - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 电脑桌面任务提醒工具_v2.2 - 秋记Autumn-个人博客,网络日杂,生活记录,一个八零后博主的日常记录。 电脑桌面任务提醒工具,每月指定日期提醒 - 秋記Autumn 长鑫科技上市,A股换了老大 - 秋記Autumn 当下年轻人只喝饮料不喝水的现状 - 秋記Autumn 长期吃布洛芬,肾脏撑不住了,血也跟着出问题 - 秋記Autumn 任意形状截图与图片裁剪工具 - 秋記Autumn 下班后,真正改变普通人的4个小时,拉开人与人之间差距的,不是上班8小时,而是下班后的4小时。 - 秋記Autumn 牛马必备!一键Windows重装和Office部署工具,装完免登录 - 秋記Autumn 谁制造了躺平、黄毛与蹦老头? - 秋記Autumn OpenAI Codex绿色免安装版+接入Deepseek教程+安装使用攻略 两款微信多开软件,一台电脑同时打开多个微信,神器! 10亩地小麦,能买一部iPhone17吗? 从顶流到停摆再重启,天涯重启首日被挤爆 微信聊天记录一键导出备份与查看 男人最硬的底气,是家里还有个人等你 你是不是已经有酒瘾了? 你正在影响谁,你可能不知道,微光也能照亮自己的路 80后赶上了,也赶不上了 “崩老头”灰色产业链,中年人的情感困局与骗局背后的社会隐忧 [开源]一款用于2D图像创作的编辑器,可用于绘制像素画、制作动画、编辑图片和设计 Logo,支持像素、绘画和矢量等多种创作方式。
给KindEditor编辑器添加一键排版功能 - 秋记Autumn-个人博客...
https://www.zhyok.cn/author/1/ · 2026-09-11 · via 秋記Autumn - 秋記Autumn

 发布博客文章编辑器用的是KindEditor,这编辑器的排版功能很弱,字体、字号、行距、首行缩进,想调齐了得一段一段手动点。我都是先在 Word 里排好版,再整段复制进编辑器。

很麻烦,Word 里排得整整齐齐,粘到网页上往往变样,右边参差不齐,回头还得手动补一遍;有时候隔几天再发一篇,版式又跟前一篇对不上。后来想想,这事的规则其实是死的,字体多大、缩进多少、行距几倍,翻来覆去就那几个数,每回手动点一遍实在没必要。那不如做成一个按钮:选中正文,点一下,参数一次套齐。

按钮怎么挂上去

工具栏得先认得这个名字。在 editor/kindeditor.jsitems 数组末尾加上 'wordfmt'

KE.lang['wordfmt'] = '格式排版(先选中文字再点)';
KE.plugin['wordfmt'] = {
click : function(id) {
if (window.wordFmt) window.wordFmt.apply(id);
}
};

再回 Plugin.php,给它配提示文字和点击动作:

KE.lang 那句会变成鼠标停在按钮上的提示。我特意写清"先选中文字再点",因为这按钮不选中就不干活,不提醒一句,点完没反应的人会以为坏了。

图标没什么玄机,给 .ke-icon-wordfmt 挂一张背景图就行。我用了四条长短不一的横线,看着像文字排整齐的样子:

KE.lang['wordfmt'] = '格式排版(先选中文字再点)';
KE.plugin['wordfmt'] = {
click : function(id) {
if (window.wordFmt) window.wordFmt.apply(id);
}
};

最后把新文件引进来,末尾的版本号别忘,文件以后改了要跟着往上加,不然浏览器和 CDN 还在读缓存的旧文件:

<script type="text/javascript" charset="utf-8" src="{$editor_path}/wordfmt.js?v=4"></script>

点下去之后做了什么

逻辑都在 wordfmt.js

编辑器是 iframe 结构,选区要从 iframe 自己的 window 里拿,用外层的拿不到。先看有没有选中东西,光标点一下没选中的要拦住,不然一按整篇都会被改:

var doc = g.iframeDoc;
var sel = g.iframeWin.getSelection ? g.iframeWin.getSelection() : null;
if (!sel || sel.rangeCount === 0) {
alert('请先选中要排版的文字,再点"格式"。');
return;
}
var range = sel.getRangeAt(0);
if (range.collapsed) { // 光标点了一下、没选中任何内容
alert('请先选中要排版的文字,再点"格式"。');
return;
}

然后把跟选区相交的块级元素挑出来。这里只处理"叶子块",也就是里面不再套段落的那些。不这么筛的话,外层一个 div 套着三个 p,div 和里面三个 p 全进名单,同一段文字要被处理两遍:

function pickBlocks(doc, range) {
var candidates = doc.body.querySelectorAll('p,div,li,blockquote,h1,h2,h3,h4,h5,h6,figure,section,article,td,th,pre');
var picked = [];
for (var i = 0; i < candidates.length; i++) {
var el = candidates[i];
if (!intersects(range, el)) continue;
if (tag(el) === 'PRE') continue; // 代码块不参与
// 里面还套着块级元素的,说明不是叶子块,交给它里面的元素处理
if (el.querySelector('p,div,li,blockquote,h1,h2,h3,h4,h5,h6,figure,section,article,td,th,pre,table,ul,ol')) continue;
if (el.closest && el.closest('pre')) continue; // 代码块里的内容一概不碰
picked.push(el);
}
return picked;
}

样式没什么花活,就是把参数拼成字符串写进内联 style

var P_STYLE = [
'font-family:Microsoft YaHei,微软雅黑,sans-serif',
'font-size:11pt',
'color:#000000',
'line-height:2.5',
'text-indent:26.5pt',
'margin:0 0 14.4pt',
'text-align:justify',
'text-shadow:1px 1px 3px rgba(0,0,0,0.25)'
].join(';');

列表和引用块不给缩进和段距,那两样套上去看着别扭,只留字体、行距和阴影:

var PLAIN_STYLE = [
'font-family:Microsoft YaHei,微软雅黑,sans-serif',
'font-size:11pt',
'color:#000000',
'line-height:2.5',
'text-shadow:1px 1px 3px rgba(0,0,0,0.25)'
].join(';');

标题、代码块、表格整个跳过。它们本来就有自己的样式,标题该有标题的字号,代码块里是它自己的高亮配色,硬套正文字体只会变难看:

var SKIP_TAGS = {
H1:1, H2:1, H3:1, H4:1, H5:1, H6:1,
PRE:1, TABLE:1, THEAD:1, TBODY:1, TR:1, TD:1, TH:1,
CODE:1, SCRIPT:1, STYLE:1, TEXTAREA:1
};

最后把这个动作记进撤销栈,不然点错了退不回去:

try { KE.toolbar.updateState(id); } catch (e) {}
try { KE.history.add(id, false); } catch (e) {}

前台兜底

有一点得先说:这个编辑器落库的段落是 <div style="...">,不是 <p>。我是点完按钮去前台看,才发现正文里全是 div。所以兜底 CSS 两种都要管上:

#article-body p,
#article-body > div:not([class]) {
font-family: Microsoft YaHei, 微软雅黑, sans-serif !important;
font-size: 11pt !important;
color: #000 !important;
text-indent: 26.5pt !important;
line-height: 2.5 !important;
margin: 0 0 14.4pt !important;
text-align: justify !important;
}

> div:not([class]) 这个限制是有意加的,只认没有类名的直接子 div,代码卡片、插件容器那些都带类名,这么写不会误伤到它们。

这套 CSS 是给没点过按钮的老文章兜底的,让新旧文章看起来一致。有一点容易想错:内联样式的优先级比 CSS 高,加 !important 也压不过。所以想让某篇文章的样式变,只能动内联样式,光改 CSS 没用。

平常怎么用

后台写文章,正文粘进来,鼠标选中,点工具栏那个"格式"按钮,就完了。选中的部分套上统一排版,标题和代码块原样不动。不选东西直接点会弹提示,不会乱改内容。手快误点了,Ctrl+Z 退回来。

效果预览


喜欢作者

一键排版