你如何在 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
命令,因为插入原始 ul
和 li
似乎会破坏列表功能)并删除 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' }
这不需要编码即可实现,并允许您确定可以启动列表的文本。上面的示例允许列表以星号或破折号开头,但您可以根据需要自定义该列表。
许多应用程序(例如 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
命令,因为插入原始 ul
和 li
似乎会破坏列表功能)并删除 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' }
这不需要编码即可实现,并允许您确定可以启动列表的文本。上面的示例允许列表以星号或破折号开头,但您可以根据需要自定义该列表。