找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 80|回复: 0

[维护日志] [2026-08-24] [功能] [编辑器字号] - 所见即所得编辑器自动添加 [size] 标签问题修复

[复制链接]
  • 打卡等级:本地老炮

9337

威望

7448

金钱

1万

贡献

管理员

自由的灵魂

积分
107434
主题
5630
回帖
26661
注册时间
2003-4-10
最后登录
2026-10-2
发表于 2026-8-24 23:26:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一、问题缘起

截图202608242329002828.webp
使用中发现,后台设置“帖子内容字号”为14px后,在论坛发帖使用所见即所得(WYSIWYG)编辑器时,粘贴内容会自动被包裹 [ size=14px ] 标签,导致:

  • 代码冗余:每段文字都被[ size=14px ] ... [ /size ] 包裹,增加不必要的 BBcode
  • 影响阅读:部分用户使用的 14px 字号与论坛默认显示不一致,导致排版混乱
  • 编辑困难:切换到纯文本模式时,大量 [size] 标签干扰内容编辑
  • 影响美观:帖子源码充斥着无意义的标签,不专业
  • 浏览器差异:问题仅在 Microsoft Edge 浏览器中出现,Firefox 正常

探讨过程中提出的独立问题汇总:

序号问题结论
1 标签由谁生成?所见即所得编辑器在粘贴内容时自动添加
2为什么编辑器会认为 14px 需要添加 [size] 标签?编辑器 iframe 的 <body> 没有设置 font-size,浏览器使用默认字号(通常 12px 或 16px),粘贴内容中的 14px 被视为“差异样式”,被自动转换为 [size] 标签
3修改 editor.css 为何无效?editor.css 控制的是纯文本模式(textarea)下的编辑框字号,而所见即所得模式是一个独立的 iframe,其样式由 editor.js 初始化时决定,两者互不关联
4为什么只有 Edge 浏览器有此问题?Edge(及 Chrome)在粘贴纯文本时,会将其“包裹”一层默认样式以保持视觉一致性,从而触发 [size] 标签生成;Firefox 则直接作为纯文本插入,不添加额外样式
5为什么只有从记事本复制的无格式文本会触发?有格式的文本(如从网页复制)自带样式信息,编辑器能正确处理;无格式文本会被浏览器赋予默认样式,从而触发 [size] 标签的生成
6后台 {MSGFONTSIZE} 与编辑器字号是什么关系?后台设置仅控制前台帖子显示,编辑器初始化时并不读取该值


二、解决方案

(1)简要技术分析

采用三重策略:① 在编辑器 iframe 初始化时,给 <body> 标签添加 style="font-size:14px",消除样式差异;② 在粘贴事件中拦截纯文本,强制使用 insertText 或直接操作 textarea.value 插入,阻止浏览器自动添加样式;③ 根据编辑模式(可视化/纯文本)选择不同的插入方式,避免 execCommand 在纯文本模式下报错。

(2)修改文件列表(完整路径)

文件修改位置控制对象
/static/js/editor.jswriteEditorContents 函数可视化模式(iframe body 字号)
/static/js/editor.jssetEditorEvents 函数粘贴事件拦截(纯文本处理,含模式判断)
/template/default/common/editor.css.edt .pt 规则纯文本模式(textarea 字号)


(3)关键作用代码段

文件 1:/static/js/editor.js(writeEditorContents 函数)

修改前:

  1. '</head><body>' + text + '</body></html>';
复制代码


修改后:

  1. '</head><body style="font-size:14px">' + text + '</body></html>';
复制代码


文件 2:/static/js/editor.js(setEditorEvents 函数)

修改后完整代码:

  1. function setEditorEvents() {
  2.     if(BROWSER.firefox || BROWSER.opera) {
  3.         editdoc.addEventListener('mouseup', function(e) {mouseUp(e)}, true);
  4.         editdoc.addEventListener('keyup', function(e) {keyUp(e)}, true);
  5.         editwin.addEventListener('keydown', function(e) {keyDown(e)}, true);
  6.         // ----- 新增:paste 事件监听(纯文本粘贴拦截) -----
  7.         editdoc.addEventListener('paste', function(e) {
  8.             var clipboardData = e.clipboardData || window.clipboardData;
  9.             if (!clipboardData) return;
  10.             var text = clipboardData.getData('text/plain');
  11.             if (text) {
  12.                 e.preventDefault();
  13.                 if (wysiwyg) {
  14.                     editdoc.execCommand('insertText', false, text);
  15.                 } else {
  16.                     var start = editdoc.selectionStart;
  17.                     var end = editdoc.selectionEnd;
  18.                     var value = editdoc.value;
  19.                     editdoc.value = value.substring(0, start) + text + value.substring(end);
  20.                     editdoc.selectionStart = editdoc.selectionEnd = start + text.length;
  21.                 }
  22.             }
  23.         }, true);
  24.         // -------------------------------------------------
  25.     } else if(editdoc.attachEvent) {
  26.         try{
  27.             editdoc.attachEvent('onmouseup', mouseUp);
  28.             editdoc.attachEvent('onkeyup', keyUp);
  29.             editdoc.attachEvent('onkeydown', keyDown);
  30.             // ----- 新增:paste 事件监听(IE 兼容写法) -----
  31.             editdoc.attachEvent('onpaste', function(e) {
  32.                 e = e || window.event;
  33.                 var clipboardData = e.clipboardData || window.clipboardData;
  34.                 if (!clipboardData) return;
  35.                 var text = clipboardData.getData('text');
  36.                 if (text) {
  37.                     e.returnValue = false;
  38.                     if (wysiwyg) {
  39.                         var range = editdoc.selection.createRange();
  40.                         range.text = text;
  41.                     } else {
  42.                         var start = editdoc.selectionStart;
  43.                         var end = editdoc.selectionEnd;
  44.                         var value = editdoc.value;
  45.                         editdoc.value = value.substring(0, start) + text + value.substring(end);
  46.                         editdoc.selectionStart = editdoc.selectionEnd = start + text.length;
  47.                     }
  48.                 }
  49.             });
  50.             // ------------------------------------------------
  51.         } catch(e) {}
  52.     }
  53. }
复制代码


文件 3:/template/default/common/editor.css

修改前:

  1. .edt .pt { padding: 0 !important; width: 100%; height: 400px; border: none; background: {WRAPBG} none; font-size: {MSGFONTSIZE}; }
复制代码


修改后:

  1. .edt .pt { padding: 0 !important; width: 100%; height: 400px; border: none; background: {WRAPBG} none; font-size: 14px; }
复制代码


三、最终实现效果

测试场景修改前修改后
所见即所得模式粘贴内容(任意来源)自动添加 标签不再生成任何 [size] 标签
Edge 浏览器粘贴纯文本被添加 正常插入,无标签
Firefox 浏览器粘贴纯文本正常正常(不受影响)
粘贴富文本(带格式)正常保留格式正常保留格式(不受影响)
纯文本模式粘贴报错 execCommand is not a function正常插入
编辑器显示闪烁或不一致稳定 14px
纯文本模式编辑框字号由 {MSGFONTSIZE} 控制固定 14px
用户手动选择字号正常生成 等标签正常生成(不受影响)
后台 {MSGFONTSIZE} 设置被编辑器间接借用仅控制前台帖子显示


四、重要技术沉淀

  • iframe 独立文档环境的隔离性:iframe 内部是一个完全独立的文档,主页面的 CSS 无法控制其内部样式。调试时需注意区分“主页面样式”和“iframe 内部样式”两个不同的上下文
  • 编辑器字号问题的根源:[size] 标签的自动生成,源于 iframe body 缺少字号定义导致的“样式差异”。给 body 设置明确的 font-size 即可消除此行为
  • editor.css 的作用范围:该文件控制的是纯文本模式(textarea)下的编辑框字号,对可视化模式(iframe)无效,两者互不关联
  • 浏览器粘贴行为差异:Edge/Chrome 在粘贴纯文本时会自动包裹默认样式,Firefox 则直接插入纯文本。需通过 paste 事件拦截来统一行为
  • execCommand 的适用场景:document.execCommand('insertText') 仅在可视化模式(iframe document)下可用,纯文本模式(textarea)下需直接操作 value 属性,否则会报错
  • {MSGFONTSIZE} 的正确职责:该变量应仅用于控制前台帖子显示,不应被编辑器借用为生成 [size] 标签的依据

是否需要更新固化摘要:✅ 是。建议在 env-base 固化摘要的“编辑器”章节补充:所见即所得编辑器已通过修改 editor.js 固定 body 字号并拦截 paste 事件,解决自动生成 [size] 标签的问题,同时兼容可视化与纯文本两种模式。

五、进一步优化的可能性

编辑器核心升级:Discuz! 编辑器版本较老,可考虑升级至更现代的编辑器(如 Quill、TinyMCE)从根本上解决此类问题,但涉及全站改造成本较高,暂不实施。
不懂就搜!点此搜点拨论坛。如果本坛没有,请尝试点此问AI,或跟帖提问。
发帖前注意看置顶帖。
不定期借助AI对点拨论坛陈年老帖进行挖坟回复,打扰勿怪!
要养成随时修正错别字的好习惯!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|点拨论坛 |网站地图

GMT+8, 2026-10-2 02:07 , Processed in 0.056529 second(s), 7 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表