[英]ContentEditable div - set cursor position after updating inner html
I have a spell check solution that uses a content editable div
and inserts span
tags around words that are misspelled.我有一个拼写检查解决方案,它使用内容可编辑的
div
并在拼写错误的单词周围插入span
标签。 Every time the inner html of the div
is updated, the cursor moves to the beginning of the div
.每次更新
div
的内部 html 时,光标都会移动到div
的开头。
I know I can move the cursor to the end of the div
if the user adds new words to the end of the sentence (code below).我知道如果用户在句子的末尾添加新单词(下面的代码),我可以将光标移动到
div
的末尾。
Old Text: This is a spell checker|
旧文本:这是拼写检查器|
New Text: This is a spell checker soluuution|
新文本:这是一个拼写检查解决方案|
var range = document.createRange();
range.selectNodeContents(element[0]);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
However, I am unable to retain the cursor position if the user adds words in the middle of a sentence.但是,如果用户在句子中间添加单词,我将无法保留光标位置。
Old Text: This is a spell checker
旧文本:这是一个拼写检查器
New Text: This is a new spell checker|
新文本:这是一个新的拼写检查器|
In the above case, the cursor goes to the end of the div
when it should be after "new".在上面的例子中,光标在应该在“new”之后的时候移动到
div
的末尾。
How do I retain the cursor position?如何保留光标位置? Since I am updating the html and adding nodes, saving the range before the update and adding it to the selection object isn't working.
由于我正在更新 html 并添加节点,因此在更新之前保存范围并将其添加到选择对象中不起作用。
Thanks in advance.提前致谢。
As far as I know, changing the content of the div will always have problem.据我所知,改变div的内容总会有问题。
So here is the solution that I came with.所以这是我带来的解决方案。 Please type error word such as helloo, dudeee
请输入错误词,例如 hello, dudeee
This should ideally work for textarea as well.理想情况下,这也适用于 textarea。
Solution details:解决方案详情:
// some mock logic to identify spelling error const errorWords = ["helloo", "dudeee"]; // Find words from string like ' Helloo world .. ' // Perhaps you could find a better library you that does this logic. const getWords = (data) =>{ console.log("Input: ", data); const allWords = data.split(/\\b/); console.log("Output: ", allWords) return allWords; } // Simple mock logic to identify errors. Now works only for // two words [ 'helloo', 'dudeee'] const containsSpellingError = word => { const found = errorWords.indexOf(word) !== -1; console.log("spell check:", word, found); return found; } const processSpellCheck = text => { const allWords = getWords(text); console.log("Words in the string: ", allWords); const newContent = allWords.map((word, index) => { var text = word; if(containsSpellingError(word.toLowerCase())) { console.log("Error word found", word); text = $("<span />") .addClass("spell-error") .text(word); } return text; }); return newContent; } function initalizeSpellcheck(editorRef) { var editorSize = editorRef.getBoundingClientRect(); var spellcheckContainer = $("<div />", {}) .addClass("spell-check") .prop("spellcheck", "false"); var spellcheckSpan = $("<span />") .addClass("spell-check-text-content") .css({ width: editorSize.width, height: editorSize.height, position: "absolute", zIndex: -1 }); var text = $(editorRef).text(); var newContent = processSpellCheck(text); spellcheckSpan.append(newContent); spellcheckContainer.append(spellcheckSpan); spellcheckContainer.insertBefore(editorRef); $(editorRef).on("input.spellcheck", function(event) { var newText = $(event.target).text(); var newContent = processSpellCheck(newText); $(".spell-check .spell-check-text-content").text(""); $(".spell-check .spell-check-text-content").append(newContent); }); } $(document).ready(function() { var editor = document.querySelector("#editor"); initalizeSpellcheck(editor); });
#editor { border: 1px solid black; height: 200px; } .spell-check { color: transparent; } .spell-error { border-bottom: 3px solid orange; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="editor" contenteditable="true" spellcheck="false"> dudeee </div>
This answer might work from SitePoint:这个答案可能适用于 SitePoint:
Store the selection x, y:存储选择 x, y:
cursorPos=document.selection.createRange().duplicate();
clickx = cursorPos.getBoundingClientRect().left;
clicky = cursorPos.getBoundingClientRect().top;
Restore the selection:恢复选择:
cursorPos = document.body.createTextRange();
cursorPos.moveToPoint(clickx, clicky);
cursorPos.select();
SitePoint Article: Saving/restoring caret position in a contentEditable div SitePoint 文章: 在 contentEditable div 中保存/恢复插入符号位置
Update 25.10.2019: 2019 年 10 月 25 日更新:
The solution mentioned above doesn't work anymore since functions are used that are deprecated.上面提到的解决方案不再起作用,因为使用了不推荐使用的函数。 Does chrome supports document.selection?
chrome 支持 document.selection 吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.