如何在TinyMCE中获取用户选中的行内节点?
解决TinyMCE选中内容时获取对应行内元素的问题
当在TinyMCE中选中行内元素(如<em>)内的文本时,tinymce.activeEditor.selection.getNode()默认返回包裹它的块级元素(如<p>),无法直接拿到目标行内元素。之前遍历块级子节点的方法仅在精确选中行内元素文本时有效,一旦选中内容包含前后空格(选区起始/结束落在文本节点上)就会失效。
正确实现方式
通过原生DOM Range对象精准定位目标行内元素,代码示例:
const editor = tinymce.activeEditor; const selectionRange = editor.selection.getRng(); let targetEm = null; // 情况1:选区起始节点的父元素是em const startParent = selectionRange.startContainer.parentNode; if (startParent.nodeName.toLowerCase() === 'em') { targetEm = startParent; } // 情况2:选区的共同祖先就是em else if (selectionRange.commonAncestorContainer.nodeName.toLowerCase() === 'em') { targetEm = selectionRange.commonAncestorContainer; } // 情况3:选区跨节点,遍历所有em元素找交集 else { const treeWalker = document.createTreeWalker( editor.getBody(), NodeFilter.SHOW_ELEMENT, { acceptNode: node => node.nodeName.toLowerCase() === 'em' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP } ); let currentNode; while (currentNode = treeWalker.nextNode()) { const nodeRange = editor.dom.createRng(); nodeRange.selectNodeContents(currentNode); // 检查当前em元素是否与选区有重叠 if (selectionRange.intersectsNode(currentNode)) { targetEm = currentNode; break; } } } // 验证结果 if (targetEm) { alert('选中的em元素内容:' + targetEm.textContent); } else { alert('未选中em元素'); }
代码说明
selection.getRng():获取用户选区的原生Range对象,能精确反映选中范围的位置,而非返回外层块级元素- 起始节点父元素检查:处理用户选中em内文本(含前后空格)的场景,此时起始节点是空格所在的文本节点,父元素就是目标em
- 共同祖先检查:处理用户完全选中em元素的场景
- TreeWalker遍历:处理选区跨多个元素的复杂场景,筛选出与选区有交集的em元素
内容的提问来源于stack exchange,提问作者Phil Gyford
相关产品推荐
相关产品推荐

