求助:无法获取wysihtml5编辑器中的光标位置
解决wysihtml5编辑器中光标位置获取返回undefined的问题
我完全懂你现在的困扰——折腾了半天写的代码,在wysihtml5编辑器里获取光标位置却一直返回undefined,连textarea里都显示这个值,太闹心了。咱们来一步步拆解问题,找到解决办法。
先揪出最显眼的小错误
你写的textarea标签拼写错了!是<textarea>不是<textaraea>,而且col和row属性也写错了,应该是cols和rows。这个小失误可能直接导致DOM元素获取异常,先把它修正:
<textarea spellcheck="false" id="editor" name="editor" data-placeholder="Transliterated Text" class="form-control" cols="5" rows="50"></textarea>
核心问题:wysihtml5不是普通textarea
你现在的代码是针对原生textarea/input写的,但wysihtml5本质是基于iframe的富文本编辑器——你看到的编辑区域其实是iframe里的body,而你写的那个textarea只是用来存储原始内容的“后台容器”,直接用原生textarea的selectionStart/selectionEnd或者IE老方法肯定无效,这就是返回undefined的核心原因。
另外,你代码里的浏览器检测逻辑太老旧了,现在Chrome、Firefox、Edge等主流浏览器都支持标准的DOM Selection API,完全不用再区分Gecko和IE老版本了。
针对wysihtml5的正确解决方案
首先确保你已经正确初始化了wysihtml5编辑器,然后用编辑器提供的API或者直接操作iframe内的文档来获取光标位置:
方法1:利用wysihtml5内置的API
// 先初始化编辑器(假设你已经有这一步) var editor = new wysihtml5.Editor("editor", { toolbar: "toolbar", // 你的工具栏配置等 // 其他配置项... }); // 获取光标起始位置 function getSelectionStart() { var selection = editor.composer.selection.getSelection(); if (!selection.rangeCount) return 0; var range = selection.getRangeAt(0); var preRange = range.cloneRange(); // 选中整个编辑区域内容 preRange.selectNodeContents(editor.composer.element); // 将range的结束位置设为光标起始位置 preRange.setEnd(range.startContainer, range.startOffset); // 返回这段内容的长度,就是光标起始位置 return preRange.toString().length; } // 获取光标结束位置 function getSelectionEnd() { var selection = editor.composer.selection.getSelection(); if (!selection.rangeCount) return 0; var range = selection.getRangeAt(0); var preRange = range.cloneRange(); preRange.selectNodeContents(editor.composer.element); preRange.setEnd(range.endContainer, range.endOffset); return preRange.toString().length; } // 测试获取光标位置的函数 function inputKey() { setTimeout(function () { document.getElementById("selStart").value = getSelectionStart(); document.getElementById("selEnd").value = getSelectionEnd(); }, 20); }
方法2:直接操作编辑器的iframe文档
如果你不想依赖wysihtml5的内置方法,也可以直接操作iframe里的文档:
function getCursorPosition() { var iframe = editor.composer.iframe; var doc = iframe.contentDocument || iframe.contentWindow.document; var selection = doc.getSelection(); if (selection.rangeCount === 0) return { start: 0, end: 0 }; var range = selection.getRangeAt(0); // 计算起始位置 var startRange = doc.createRange(); startRange.selectNodeContents(doc.body); startRange.setEnd(range.startContainer, range.startOffset); var startPos = startRange.toString().length; // 计算结束位置 var endRange = doc.createRange(); endRange.selectNodeContents(doc.body); endRange.setEnd(range.endContainer, range.endOffset); var endPos = endRange.toString().length; return { start: startPos, end: endPos }; } // 调用示例 function inputKey() { setTimeout(function () { var pos = getCursorPosition(); document.getElementById("selStart").value = pos.start; document.getElementById("selEnd").value = pos.end; }, 20); }
最后再提醒几句
- 一定要确保编辑器初始化完成后再调用这些获取光标位置的函数,不然可能拿不到正确的
editor实例。 - 如果你需要设置光标位置,同样要操作iframe内的range,而不是原生textarea的方法。
内容的提问来源于stack exchange,提问作者furquan shaikh
相关产品推荐
相关产品推荐

