You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决JS监听fancybox3 iframe内多CKEditor 5实例变更的报错

CKEditor内容变更监听报错修复方案

错误根源

  • ClassicEditor.create() 是异步Promise方法,初始化过程不会阻塞主线程执行,你在then回调外绑定事件时,编辑器实例还未创建完成,editors[index]处于未赋值的undefined状态,因此读取document属性时报错。
  • 全局editors是存储所有编辑器实例的集合对象,本身不存在document属性,因此将监听代码移到外部后依然会触发报错。

修复后代码

以下代码将事件绑定逻辑放到编辑器初始化完成的回调内,同时新增全局修改标记用于对接Fancybox逻辑,CKEditor 5推荐监听change:data事件捕获用户输入变更,触发逻辑更精准:

window.editors = {};
// 全局修改标记,父页面Fancybox可直接读取该变量判断内容状态
window.hasContentChanged = false;

document.querySelectorAll( '.editor' ).forEach( ( node, index ) => {
  ClassicEditor
    .create( node, {
      removePlugins: ['Heading', 'BlockQuote', 'CKFinderUploadAdapter', 'CKFinder', 'EasyImage', 'Image', 'ImageCaption', 'ImageStyle', 'ImageToolbar', 'ImageUpload', 'MediaEmbed'],
    } )
    .then( newEditor => {
      window.editors[ index ] = newEditor;
      // 编辑器实例创建完成后再绑定事件
      newEditor.model.document.on( 'change:data', () => {
        console.log( 'Alert: The document has changed!, are you sure you want to close without saving?' );
        // 标记内容已修改
        window.hasContentChanged = true;
      } );
    } )
    .catch( error => {
      console.error( '编辑器初始化失败', error );
    } );
} );

Fancybox对接说明

父页面Fancybox 3可以直接读取iframe的全局标记实现关闭提醒、按钮状态修改的需求,配置参考如下:

// 父页面Fancybox 3配置
$.fancybox.open({
  src: '你的iframe页面地址',
  type: 'iframe',
  // 关闭前触发的回调
  beforeClose: function(instance, current) {
    const iframeWin = current.$iframe[0].contentWindow;
    // 内容已修改时弹出确认提醒
    if (iframeWin.hasContentChanged) {
      return confirm('你有未保存的修改,确认要关闭吗?');
      // 返回false会阻止Fancybox关闭
    }
  }
  // 其他原有配置项...
});

内容保存成功后可以手动将iframe中的window.hasContentChanged重置为false即可消除提醒。

内容的提问来源于stack exchange,提问作者mark-in-motion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 13:06:03