你如何在 TinyMCE 中添加自动项目符号?

How do you add auto-bullets in TinyMCE?

许多应用程序(例如 Slack)都有一个方便的功能,如果您键入连字符 - 并在新行上点击 space,该行将自动转换为项目符号(又名无序列表)。如何在 TinyMCE 中实现这一功能?

很高兴你提出这个问题!在找到一个似乎运行良好的解决方案之前,我对该解决方案进行了几次迭代。

首先,我定义了 Autobullets 的触发字符(连字符),以及我希望在其中触发 Autobullet 的 HTML 容器(在本例中为段落、div、table 单元格和跨度):

const AUTOBULLET_TRIGGER_CHARACTER = "-";
const AUTOBULLET_VALID_CONTAINERS = [
  "HTMLTableCellElement",
  "HTMLParagraphElement",
  "HTMLDivElement",
  "HTMLElement",
];

然后,我在编辑器设置中添加了这个事件处理程序,注释为:

        editor.on("KeyUp", function (e) {
          var sel = editor.selection.getSel();
          var caretPos = sel.anchorOffset;
          var txtData = sel.anchorNode.textContent;
          
          // Char code 160 is a non breaking space
          const lineMatch = `${AUTOBULLET_TRIGGER_CHARACTER}${String.fromCharCode(
            160
          )}`;

          if (e.key === " " && caretPos === 2 && txtData === lineMatch) {
            if (
              AUTOBULLET_VALID_CONTAINERS.includes(
                sel.focusNode.parentElement.constructor.name
              )
            ) {
              // Create an unordered list
              editor.execCommand("InsertUnorderedList", false);

              // Delete the last two characters from the cursor position,
              // which we know are "- " since that's what triggered the autobullet
              //
              // Modified from 
              const edRange = editor.selection.getRng();
              const edNode = edRange.commonAncestorContainer;
              let range = document.createRange(); // create a new range object for the deletion
              range.selectNodeContents(edNode);
              range.setStart(edNode, edRange.endOffset - 2); // current caret pos - 3
              range.setEnd(edNode, edRange.endOffset); // current caret pos
              range.deleteContents();
            }
          }
        });

如您所见,处理程序检测用户是否在 keyUp 上触发了角色和 space。然后,我们插入无序列表(重要的是,我们使用 InsertUnorderedList 命令,因为插入原始 ulli 似乎会破坏列表功能)并删除 hyphen/space触发器。

仅供参考,TinyMCE 中的 textpattern 插件为您提供了一种使用(默认情况下)标记样式文本插入列表的方法:

https://www.tiny.cloud/docs/plugins/opensource/textpattern/

列表的具体选项是:

// The following text patterns require the `lists` plugin
{start: '1. ', cmd: 'InsertOrderedList'},
{start: '* ', cmd: 'InsertUnorderedList'},
{start: '- ', cmd: 'InsertUnorderedList' }

这不需要编码即可实现,并允许您确定可以启动列表的文本。上面的示例允许列表以星号或破折号开头,但您可以根据需要自定义该列表。