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

TinyMCE 6.x自定义按钮插入HTML:v4.x迁移遇阻求助

TinyMCE v4 升级到 v6:自定义弹窗按钮适配方案

问题场景

之前在TinyMCE v4.x里已经实现需求:自定义按钮点击后打开带参数的弹窗,用户操作生成HTML后通过editor.insertContent()插入编辑器对应位置。但升级到v6.x时遇到三个问题:

  • 最初写的v6代码里按钮能显示,但点击没反应,后来发现得用editor.windowManager.openUrl()替代原来的open();
  • 没法像v4那样通过top.tinymce.activeEditor.windowManager.getParams()获取弹窗参数,虽然能用URL传参,但想找官方更稳健的方式;
  • 还没搞定把弹窗生成的HTML回传给编辑器的问题。

原v4按钮实现代码

editor.addButton('myButton', {
  text: 'XYZ',
  tooltip: 'Do something',
  icon: false,
  onclick: function () {
    editor.windowManager.open({
      title: 'XYZ',
      url: 'mypopuppage.html',
      width: 800,
      height: 600
    }, { 
      arg0: '0',
      arg1: '1',
      arg2: editor.selection.getContent({ format: 'html' }),
      arg3: '',
      arg4: ''
    });
  }
});

尝试的v6代码(存在问题)

tinymce.init({
  selector: "textarea#txtA",
  menubar: false,
  statusbar: false,
  plugins: "myButton",
  setup: (editor) => {
    editor.ui.registry.addButton('myButton', {
      text: 'XYZ',
      onAction: (_) =>  {
        editor.windowManager.open({
          title: 'XYZ',
          url: 'mypopuppage.html',
          width: 800,
          height: 600
        }, {
          arg0: '0',
          arg1: '1',
          arg2: editor.selection.getContent({ format: 'html' }),
          arg3: '',
          arg4: ''
        });
      }
    });
  },
  toolbar1: "myButton"
});

完整解决方案

1. 修正弹窗调用API

TinyMCE v6里打开URL弹窗的API换成了editor.windowManager.openUrl(),参数结构也做了调整,原来的第二个参数要合并到params字段里。

2. 官方稳健的参数传递与获取

v6里通过openUrl()的params选项传递参数,弹窗页面用tinymce.activeEditor.windowManager.getParams()就能拿到,不用靠URL拼接,更可靠。

3. HTML回传至编辑器

有两种方式:一是弹窗直接调用编辑器的insertContent()插入内容;二是弹窗把数据传给弹窗API,编辑器监听onClose事件接收数据后插入。

修正后的v6编辑器代码

tinymce.init({
  selector: "textarea#txtA",
  menubar: false,
  statusbar: false,
  setup: (editor) => {
    editor.ui.registry.addButton('myButton', {
      text: 'XYZ',
      tooltip: 'Do something',
      icon: false,
      onAction: () => {
        editor.windowManager.openUrl({
          title: 'XYZ',
          url: 'mypopuppage.html',
          width: 800,
          height: 600,
          // 传递参数到弹窗
          params: {
            arg0: '0',
            arg1: '1',
            arg2: editor.selection.getContent({ format: 'html' }),
            arg3: '',
            arg4: ''
          },
          // 监听弹窗关闭,接收回传数据
          onClose: (api) => {
            const returnData = api.getData();
            if (returnData?.htmlContent) {
              editor.insertContent(returnData.htmlContent);
            }
          }
        });
      }
    });
  },
  toolbar1: "myButton"
});

弹窗页面(mypopuppage.html)代码示例

<!DOCTYPE html>
<html>
<head>
  <title>XYZ弹窗</title>
  <!-- 必须加载TinyMCE的JS文件,才能调用编辑器相关API -->
  <script src="//cdn.tiny.cloud/1/你的API密钥/tinymce/6/tinymce.min.js"></script>
</head>
<body>
  <textarea id="htmlInput" rows="10" cols="80"></textarea>
  <button onclick="sendToEditor()">插入到编辑器</button>

  <script>
    // 获取编辑器传递的参数
    const popupParams = tinymce.activeEditor.windowManager.getParams();
    // 用选中的内容初始化弹窗输入框
    document.getElementById('htmlInput').value = popupParams.arg2;

    function sendToEditor() {
      const generatedHtml = document.getElementById('htmlInput').value;
      
      // 方式1:直接调用编辑器插入内容,然后关闭弹窗
      tinymce.activeEditor.insertContent(generatedHtml);
      tinymce.activeEditor.windowManager.close();

      // 方式2:通过API传递数据,编辑器在onClose中接收
      // const api = tinymce.activeEditor.windowManager.getApi();
      // api.setData({ htmlContent: generatedHtml });
      // tinymce.activeEditor.windowManager.close();
    }
  </script>
</body>
</html>

注意事项

  • 弹窗页面必须加载TinyMCE的JS文件,否则无法访问tinymce.activeEditor相关方法;
  • 如果弹窗和编辑器不在同一域名下,需要配置TinyMCE的跨域选项,或者改用postMessage进行通信;
  • v6中不再支持v4那种open()的第二个参数传参方式,必须统一放在openUrl()的params字段里。

内容的提问来源于stack exchange,提问作者PSU

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:57:38