如何在TinyMCE源代码视图中恢复光标位置
解决TinyMCE源代码视图光标位置丢失问题
你可以通过监听TinyMCE的视图切换事件,手动保存光标位置并在视图切换完成后恢复。以下是两种可行的实现方案:
方案1:基于富文本内容的光标偏移量保存恢复
利用BeforeGetContent和SetContent事件,在切换到源码视图前计算光标在富文本内容中的字符偏移量,切换回富文本视图后根据偏移量定位光标:
tinymce.init({ selector: '#your-editor-id', plugins: 'code', setup: function(editor) { let savedCursorOffset = 0; // 切换到源码视图前,保存光标在富文本中的字符偏移量 editor.on('BeforeGetContent', function(e) { // 仅在获取原始HTML内容(源码视图触发)时执行 if (e.format === 'raw' && !e.draft) { const selectionRange = editor.selection.getRng(); const fullContentRange = editor.dom.createRng(); fullContentRange.selectNodeContents(editor.getBody()); // 计算从内容开头到光标位置的字符长度 fullContentRange.setEnd(selectionRange.startContainer, selectionRange.startOffset); savedCursorOffset = fullContentRange.toString().length; } }); // 从源码视图切换回富文本后,恢复光标位置 editor.on('SetContent', function(e) { if (e.format === 'raw' && !e.draft) { // 延迟执行确保DOM渲染完成 setTimeout(function() { const contentBody = editor.getBody(); const targetRange = editor.dom.createRng(); const textNode = editor.dom.selectNode(contentBody); // 根据保存的偏移量设置光标位置 targetRange.setStart(textNode, savedCursorOffset); targetRange.setEnd(textNode, savedCursorOffset); editor.selection.setRng(targetRange); }, 100); } }); } });
方案2:基于源码视图textarea的光标位置保存恢复
直接监听源码视图的切换事件,保存源码textarea中的光标位置,切换回富文本时将该位置映射到富文本内容中:
tinymce.init({ selector: '#your-editor-id', plugins: 'code', setup: function(editor) { let sourceCursorPos = 0; editor.on('SwitchMode', function(e) { const sourceTextarea = editor.getContainer().querySelector('textarea'); if (!sourceTextarea) return; // 切换到源码视图时保存光标位置 if (e.mode === 'code') { sourceCursorPos = sourceTextarea.selectionStart; } // 切换回富文本视图时恢复光标 else { // 先更新源码视图的光标位置(避免编辑后未保存) sourceCursorPos = sourceTextarea.selectionStart; setTimeout(function() { const contentText = editor.getContent({ format: 'text' }); // 确保偏移量不超过内容长度 const targetOffset = Math.min(sourceCursorPos, contentText.length); const contentBody = editor.getBody(); const targetRange = editor.dom.createRng(); const textNode = editor.dom.selectNode(contentBody); targetRange.setStart(textNode, targetOffset); targetRange.setEnd(textNode, targetOffset); editor.selection.setRng(targetRange); }, 100); } }); } });
注意事项
- 字符偏移量的方法可能因HTML标签与纯文本的差异存在轻微误差,若需要更高精度,可以尝试保存光标所在的DOM节点路径和节点内的偏移量,而非纯字符数。
setTimeout的延迟时间可根据你的页面渲染速度调整,确保DOM完全更新后再执行光标恢复操作。- 若使用了第三方源码编辑插件,需调整
querySelector的选择器以正确获取源码编辑的textarea元素。
内容的提问来源于stack exchange,提问作者Kazu
相关产品推荐
相关产品推荐

