如何让Summernote与jQuery DirtyForms联动检测富文本内容变更?
解决Summernote与jQuery DirtyForms联动检测内容变更的问题
我懂你的困扰——Summernote在可视化编辑模式下,DirtyForms完全检测不到内容变化,只有切到代码视图才会触发脏状态标记,这确实挺闹心的。本质原因是Summernote的可视化编辑是在iframe里渲染内容的,DirtyForms默认只监听原生表单元素的change事件,没法捕获富文本编辑器内部的内容变动。
下面是具体的解决思路和修改后的代码:
核心解决思路
- 利用Summernote原生的
summernote.change事件,这个事件在可视化/代码视图下内容发生变化时都会触发 - 在该事件中手动通知DirtyForms表单已修改,强制它重新检测表单状态
- 同步联动保存按钮的启用/禁用状态
修改后的完整代码
var formUpdateChecker = function() { // 设置DirtyForms需要忽略的类名 $s.DirtyForms.ignoreClass = 'ignore-dirty'; // 初始化DirtyForms到目标表单 var $targetForms = $s('form#product-update, form#form-discount, form#draftComanda, form#product-add, #form--addNewAddress, #form--editAddress'); $targetForms.dirtyForms({ message: 'Ai facut modificari care ar putea sa nu fie salvate.' }); // 监听表单状态事件 + Summernote内容变更事件 $targetForms.add('#descriere').on('dirty.dirtyforms clean.dirtyforms summernote.change', function(ev) { // 确保获取到当前元素对应的父表单(针对Summernote元素触发的事件) var $form = $s(ev.target).closest('form'); var $submitResetButtons = $s('.btn-save'); if (ev.type === 'summernote.change') { // 当Summernote内容变化时,手动标记表单为脏状态 $form.dirtyForms('setDirty'); return; // 提前返回,避免重复处理状态切换逻辑 } // 根据表单脏/干净状态切换按钮样式与可用性 if (ev.type === 'dirty') { $submitResetButtons.removeAttr('disabled').addClass('btn-primary').removeClass('btn-default'); } else { $submitResetButtons.attr('disabled', 'disabled').removeClass('btn-primary').addClass('btn-default'); } }); };
关键修改点说明
- 精准关联表单:用
.closest('form')确保即使事件是从Summernote编辑器(#descriere)触发的,也能找到对应的父表单元素 - 手动触发脏状态:在
summernote.change事件中调用$form.dirtyForms('setDirty'),强制DirtyForms识别到内容变更 - 逻辑分离处理:把Summernote的内容变更事件和DirtyForms的状态事件分开处理,避免逻辑混乱
额外注意事项
- 确保你已经正确初始化了Summernote编辑器,比如:
$s('#descriere').summernote({ // 你的Summernote配置项,比如工具栏、高度等 }); - 如果有多个Summernote编辑器,只需把对应的选择器加入到事件监听的元素集合中即可
内容的提问来源于stack exchange,提问作者speedy




