使用场景

  • 为重复执行某一操作或一系列操作的用户创建快捷方式。

  • 为自定义行为创建按钮。

如何创建自定义工具栏按钮

添加自定义工具栏按钮的方法位于编辑器API的UI Registry部分 editor.ui.registry 中。该API提供了四种添加工具栏按钮的方法,每种类型对应一个:

  • editor.ui.registry.addButton(identifier, configuration)

  • editor.ui.registry.addToggleButton(identifier, configuration)

  • editor.ui.registry.addSplitButton(identifier, configuration)

  • editor.ui.registry.addMenuButton(identifier, configuration)

  • editor.ui.registry.addGroupToolbarButton(identifier, configuration)

这些方法需要两个参数:

  • identifier - 按钮的唯一名称

  • configuration - 包含该按钮配置的对象。

某些配置选项适用于所有类型的工具栏按钮,但某些工具栏按钮类型也有自定义配置选项。有关详细信息,请参阅每种按钮类型的相关文档。

要创建自定义工具栏按钮,请在TinyMCE配置的setup回调函数中定义并注册该按钮。此回调函数会在每个已初始化的编辑器实例中自动调用。必须在setup回调函数内定义UI组件,因为该回调函数会接收一个编辑器实例的引用作为参数,用于访问UI Registry API。注册完成后,将注册时使用的标识符字符串添加到toolbar配置选项中,即可将按钮添加到编辑器中。

添加点击时触发警告框的基础按钮示例

tinymce.init({
  selector: '#editor',
  toolbar: 'myCustomToolbarButton',
  setup: (editor) => {
    editor.ui.registry.addButton('myCustomToolbarButton', {
      text: '我的自定义按钮',
      onAction: () => alert('Button clicked!')
    });
  }
});

工具栏按钮示例

以下示例创建了不同类型的工具栏按钮。

HTML

<textarea id="toolbar-button">
  <p>Hello world</p>
</textarea>

JS

tinymce.init({
  selector: 'textarea#toolbar-button',
  toolbar: 'basicDateButton selectiveDateButton toggleDateButton splitDateButton menuDateButton',
  setup: (editor) => {

    /* 辅助函数 */
    const toDateHtml = (date) => `<time datetime="${date.toString()}">${date.toDateString()}</time>`;
    const toGmtHtml = (date) => `<time datetime="${date.toString()}">${date.toGMTString()}</time>`;
    const toIsoHtml = (date) => `<time datetime="${date.toString()}">${date.toISOString()}</time>`;

    /* 基础按钮,仅插入日期 */
    editor.ui.registry.addButton('basicDateButton', {
      text: '插入日期',
      tooltip: '插入当前日期',
      onAction: (_) => editor.insertContent(toDateHtml(new Date()))
    });

    /* 基础按钮,仅当光标当前不在“time”元素内时插入日期 */
    editor.ui.registry.addButton('selectiveDateButton', {
      icon: 'insert-time',
      tooltip: '插入当前日期',
      enabled: false,
      onAction: (_) => editor.insertContent(toDateHtml(new Date())),
      onSetup: (buttonApi) => {
        const editorEventCallback = (eventApi) => {
          buttonApi.setEnabled(eventApi.element.nodeName.toLowerCase() !== 'time');
        };
        editor.on('NodeChange', editorEventCallback);
        return () => editor.off('NodeChange', editorEventCallback);
      }
    });

    /* 切换按钮,插入日期,但当光标在“time”元素内时变为不活动状态 */
    /* 这样就不能在另一个“time”元素内插入“time”元素。同时提供视觉反馈。 */
    editor.ui.registry.addToggleButton('toggleDateButton', {
      icon: 'insert-time',
      tooltip: '插入当前日期',
      onAction: (_) => editor.insertContent(toDateHtml(new Date())),
      onSetup: (buttonApi) => {
        const editorEventCallback = (eventApi) => {
          buttonApi.setActive(eventApi.element.nodeName.toLowerCase() === 'time');
        };
        editor.on('NodeChange', editorEventCallback);
        return () => editor.off('NodeChange', editorEventCallback);
      }
    });

    /* 拆分按钮,列出3种格式,点击时按所选格式插入日期 */
    editor.ui.registry.addSplitButton('splitDateButton', {
      text: '插入日期',
      onAction: (_) => editor.insertContent('<p>Its Friday!</p>'),
      onItemAction: (buttonApi, value) => editor.insertContent(value),
      fetch: (callback) => {
        const items = [
          {
            type: 'choiceitem',
            text: '插入日期',
            value: toDateHtml(new Date())
          },
          {
            type: 'choiceitem',
            text: '插入GMT日期',
            value: toGmtHtml(new Date())
          },
          {
            type: 'choiceitem',
            text: '插入ISO日期',
            value: toIsoHtml(new Date())
          }
        ];
        callback(items);
      }
    });

    /* 菜单按钮,有一个简单的“插入日期”菜单项,以及包含其他格式的子菜单。 */
    /* 点击第一个菜单项或子菜单项之一时,按所选格式插入日期。 */
    editor.ui.registry.addMenuButton('menuDateButton', {
      text: '日期',
      fetch: (callback) => {
        const items = [
          {
            type: 'menuitem',
            text: '插入日期',
            onAction: (_) => editor.insertContent(toDateHtml(new Date()))
          },
          {
            type: 'nestedmenuitem',
            text: '其他格式',
            getSubmenuItems: () => [
              {
                type: 'menuitem',
                text: 'GMT',
                onAction: (_) => editor.insertContent(toGmtHtml(new Date()))
              },
              {
                type: 'menuitem',
                text: 'ISO',
                onAction: (_) => editor.insertContent(toIsoHtml(new Date()))
              }
            ]
          }
        ];
        callback(items);
      }
    });
  },
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});