☰
layui layedit.js 扩展字号、字体颜色、背景颜色完整实现与避坑指南
2026/10/14 15:10:26 网站建设 项目流程

简介:这份资源是 layui 富文本编辑器 layedit.js 的完整功能演示与源码包,面向使用 layui 框架进行模块化 Web 开发的前端工程师,尤其适合需要为后台管理系统或内容发布平台集成编辑器的开发者。它围绕字体大小、字体颜色与背景颜色三大核心编辑能力展开,同时覆盖插入表格、批量上传图片、图片尺寸与对齐控制、超链接与视频插入、全屏编辑、段落格式及锚点导航等扩展功能,可帮助读者快速理解并复用一套功能全面的内容编辑方案。压缩包共 126 个文件,约 849KB,以 75 个 gif 演示动图、29 个 js 脚本、6 个 css 样式、4 个 html 示例页面为主,另含字体图标与少量配置说明文件,结构清晰便于按模块查阅。目前已有 262 人学习下载,适合希望低成本掌握 layui 富文本定制与二次开发的前端从业者参考。

1. 从一次后台改版说起:layedit.js 的字体样式到底卡在哪

去年帮一个做设备巡检系统的团队改后台,需求很朴素:巡检记录用富文本录入,重点参数要能标红、标大、标黄底。他们用的是 layui 的layedit.js,结果一上手就发现——工具栏里根本没有字号、字体颜色、背景颜色这三个按钮。翻遍官方文档,layedit只给了加粗、斜体、下划线、删除线、链接、图片、分割线这些基础项,样式类操作是缺的。这不是配置没开,是组件本身没做。

layedit.js是 layui 早期版本里自带的轻量富文本组件,定位就是「够用就行」,底层走的是document.execCommand这套浏览器原生编辑命令。它的工具栏是写死在源码里的一个数组,想加按钮就得改源码或者做扩展。所以「字体大小、字体颜色、背景颜色」这三个需求,本质上是给layedit做一次工具栏扩展 + 命令注入。

这篇笔记面向的是正在用 layui 做后台、被layedit样式功能卡住的前后端。我会把扩展的完整思路、可直接抄的代码、参数怎么调、以及我实际踩过的几个坑讲清楚。如果你用的是 layui 2.x 且不想换富文本组件,这套改法能直接落地;如果你在选型阶段,也能从这些坑里判断layedit到底值不值得留。

2. 拆开 layedit.js:工具栏结构、execCommand 与扩展点

2.1 layedit 的工具栏是怎么渲染出来的

layedit.js内部维护了一个tool数组,每一项形如['bold', 'strong']或['italic'],渲染时遍历这个数组生成<li>标签,点击时根据第一项的名字去查一个内部命令映射表,最终调用document.execCommand。也就是说,工具栏按钮和实际执行的命令是两套东西:按钮负责显示图标和绑定事件,命令表负责真正改 DOM。

关键点在于,layedit暴露了一个layedit.set(options)方法,其中options.tool可以覆盖默认工具栏。但注意——覆盖工具栏只能改按钮的显示,不能凭空造出execCommand不认识的命令。fontSize、foreColor、backColor这三个命令浏览器原生是支持的,所以只要把按钮加上、把命令名对上,就能跑通。这是整个扩展能成立的前提。

常见做法是:不改layedit.js源文件,而是在页面初始化前用layedit.set注入自定义tool数组,再在layedit.build之后手动给新按钮绑事件。这样升级 layui 版本时不会因为改了源码而冲突。

2.2 execCommand 的三个样式命令与取值规则

document.execCommand里和这次需求直接相关的是:

命令作用取值示例备注
fontSize字号1~7只接受 1-7 的档位,不是 px
foreColor字体颜色#ff0000/red支持十六进制和颜色名
backColor背景颜色#ffff00部分浏览器对选区处理有差异

这里第一个坑就来了:fontSize的取值是 1 到 7 的档位,不是像素值。很多人想传16px,结果命令直接失效,控制台也不报错,就是没反应。1 档最小、7 档最大,实际渲染出来的大小由浏览器默认样式决定,通常是 7 档约等于 36px 左右。如果你需要精确像素,得改用styleWithCSS配合自定义 span,那是另一套做法,本文先按档位来,够用且稳。

foreColor和backColor在选区为空(光标没选中文字)时,部分浏览器会作用于后续输入,部分浏览器直接忽略。所以交互上要引导用户先选中文字再点颜色,否则会出现「点了没反应」的玄学现象。

2.3 扩展点的选择:改源码还是外部注入

两条路:

  • 改源码:直接在layedit.js的tool数组里加项,在命令映射里加分支。优点是干净,缺点是升级即覆盖,维护成本高。
  • 外部注入:用layedit.set覆盖tool,再在build后补事件。优点是不动源文件,缺点是事件绑定要自己写,稍微绕一点。

我一般选外部注入,因为后台项目往往锁死 layui 版本,但偶尔也会跟着升,改源码的后悔药不好吃。下面第 3 章就按外部注入来写完整实现。

3. 动手扩展:字号、字体颜色、背景颜色三个按钮的完整实现

3.1 引入与初始化:先 set 再 build

先看页面结构。假设你已经引入了 layui 的 css 和 js,富文本容器是一个<textarea>。

<!-- 富文本容器,layedit 会把它替换成可编辑区域 --> <textarea id="content" style="display:none;"></textarea>

然后是初始化脚本。核心是layedit.set里把tool数组补全,注意fontSize、foreColor、backColor这三项要写成layedit能识别的格式。

layui.use(['layedit', 'layer'], function () { var layedit = layui.layedit; var layer = layui.layer; // 关键:在 build 之前 set,覆盖默认工具栏 layedit.set({ // 自定义工具栏,前几项保留原生能力,后面追加三个样式项 tool: [ 'strong', 'italic', 'underline', 'del', '|', 'left', 'center', 'right', '|', 'fontSize', // 字号 'foreColor', // 字体颜色 'backColor', // 背景颜色 '|', 'link', 'image' ], height: 300 }); // build 返回一个索引,后续取值、同步都靠它 var editIndex = layedit.build('content'); // build 之后,新按钮已经渲染,但点击事件需要自己接管 bindStyleEvents(layedit, editIndex); });

逻辑说明:layedit.set必须在layedit.build之前调用,否则工具栏已经按默认渲染完了,再 set 不生效。tool数组里的'|'是分隔符,渲染成竖线。fontSize、foreColor、backColor这三个名字是我自定义的标识,layedit不认识它们,所以不会自动绑命令——这正是下一步要手动接管的原因。

参数说明:height控制编辑区高度,单位 px。editIndex是build的返回值,后面layedit.getContent(editIndex)取内容时要用,别丢。

3.2 给三个按钮绑事件并调用 execCommand

layedit渲染出来的工具栏结构大致是<div class="layui-layedit-tool">里面一堆<a>或<li>。新加的按钮因为没有内置命令,点击后没反应。我们要在build之后找到它们,重新绑事件。

function bindStyleEvents(layedit, editIndex) { // 找到编辑器对应的工具栏容器 var toolBar = document.querySelector('.layui-layedit-tool'); if (!toolBar) return; // 通过按钮的>// 提交前同步,把编辑区 HTML 写回 textarea function getContent() { layedit.sync(editIndex); // 或者直接取:var html = layedit.getContent(editIndex); return document.getElementById('content').value; }

逻辑说明:sync会把编辑区内容写回原始textarea,适合表单整体提交;getContent直接返回 HTML 字符串,适合 ajax 提交。两者选一个即可,别重复取。样式标签(<font>或带 style 的 span)会原样保留在 HTML 里,后端存库时注意字段长度,带背景色的内容会比纯文本长不少。

4. 避坑与排查:样式不生效、选区丢失、升级冲突

4.1 点了按钮没反应,控制台也不报错

现象:字号、颜色按钮点下去,编辑区文字毫无变化,F12 里没有红色报错。

原因:九成是选区丢了。弹层、取色器一打开,编辑区blur,document.execCommand找不到作用目标,静默失败。另一个可能是focus调用的元素不对——layedit把textarea隐藏了,真正可编辑的是它生成的 iframe 或 contenteditable div,focus到隐藏的textarea没用。

解决:确认focus的目标是真正可编辑的那个元素。稳妥做法是在build后拿到编辑区 DOM,存成变量,绑事件时 focus 它。如果用的是 iframe 模式,要 focus 到iframe.contentDocument.body。

4.2 fontSize 传了 px 值,命令直接失效

现象:想设 16px,传了'16px',结果字号没变。

原因:execCommand('fontSize')只认 1-7 的档位,传其他值浏览器直接忽略,不报错。

解决:要么用档位,要么改用styleWithCSS+ 自定义 span 包裹选区。档位方案简单稳,像素方案灵活但代码量大。我一般先用档位顶住需求,真要做像素级再上自定义方案。

4.3 背景色在部分浏览器只作用于文字不作用于行

现象:backColor设了黄色,Chrome 里是文字底色,某些内核里变成整行背景。

原因:backColor的行为依赖浏览器对hiliteColor和backColor的实现差异,不同内核表现不一致。

解决:如果要求跨浏览器一致,改用hiliteColor(部分浏览器支持),或者干脆用styleWithCSS后手动包 span 设background-color。后台系统一般用户量可控,先按主流浏览器调,别过度设计。

4.4 升级 layui 后按钮消失或事件失效

现象:换了 layui 版本,三个按钮没了,或者点了报错。

原因:layedit在不同小版本里工具栏渲染的 DOM 结构、类名可能有微调,靠querySelector找按钮的写法会失效。

解决:把查找按钮的逻辑写得宽容一点,优先用>function initLayeditStyle(options) { var cfg = Object.assign({ fontSizeMap: { '2': '小', '4': '正常', '5': '大', '6': '特大' }, defaultColor: '#ff0000', enableBackColor: true }, options || {}); // 按 cfg 动态生成字号按钮 var fsHtml = Object.keys(cfg.fontSizeMap).map(function (size) { return '<button class="fs-btn" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;" />

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询