Javascript 更改内容后恢复光标位置可编辑
有这样的html:Javascript 更改内容后恢复光标位置可编辑,javascript,jquery,html,contenteditable,Javascript,Jquery,Html,Contenteditable,有这样的html: <div contenteditable="true" class="value research-form thumbnail"> Some text here </div> 这里有一些文字 div的内容应该动态地突出显示一些单词,而用户类型,例如: <div contenteditable="true" class="value research-form thumbnail"> Some text here <sp
<div contenteditable="true" class="value research-form thumbnail">
Some text here
</div>
这里有一些文字
div的内容应该动态地突出显示一些单词,而用户类型,例如:
<div contenteditable="true" class="value research-form thumbnail">
Some text here <span style="background-color: yellow">highlight</div> it
</div>
<script>
$(document).ready(function () {
var input = $('#textarea').on('input', function (event) {
var newText = input.text().replace('highlight', '<span style="background-color: yellow">highlight</div>');
input.html($.parseHTML(newText));
});
});
</script>
这里的一些文字突出显示了它
$(文档).ready(函数(){
变量输入=$('#textarea')。在('input',函数(事件)上{
var newText=input.text().replace('highlight','highlight');
html($.parseHTML(newText));
});
});
但有一个问题:当我刷新div中的文本时,光标在input中文本的开头移动
更改contenteditable值后,是否有方法恢复光标位置?或者有其他方法可以达到同样的效果?我找到了解决办法
以下是完整的代码:
<div class="container" style="margin-top: 10px">
<div class="thumbnail value" contenteditable="true">
</div>
</div>
<script>
$(document).ready(function () {
function getCaretCharacterOffsetWithin(element) {
var caretOffset = 0;
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
var sel;
if (typeof win.getSelection != "undefined") {
sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = win.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
caretOffset = preCaretRange.toString().length;
}
} else if ((sel = doc.selection) && sel.type != "Control") {
var textRange = sel.createRange();
var preCaretTextRange = doc.body.createTextRange();
preCaretTextRange.moveToElementText(element);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
caretOffset = preCaretTextRange.text.length;
}
return caretOffset;
}
function setCaretPosition(element, offset) {
var range = document.createRange();
var sel = window.getSelection();
//select appropriate node
var currentNode = null;
var previousNode = null;
for (var i = 0; i < element.childNodes.length; i++) {
//save previous node
previousNode = currentNode;
//get current node
currentNode = element.childNodes[i];
//if we get span or something else then we should get child node
while(currentNode.childNodes.length > 0){
currentNode = currentNode.childNodes[0];
}
//calc offset in current node
if (previousNode != null) {
offset -= previousNode.length;
}
//check whether current node has enough length
if (offset <= currentNode.length) {
break;
}
}
//move caret to specified offset
if (currentNode != null) {
range.setStart(currentNode, offset);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
function onInput(event) {
var position = getCaretCharacterOffsetWithin(input.get(0));
var text = input.text();
text = text.replace(new RegExp('\\btest\\b', 'ig'), '<span style="background-color: yellow">test</span>');
input.html($.parseHTML(text));
setCaretPosition(input.get(0), position);
}
var input = $('.value').on('input',onInput);
//content should be updated manually to prevent aditional spaces
input.html('simple input test example');
//trigger event
onInput();
});
</script>
$(文档).ready(函数(){
函数getCaretCharacterOffsetWithin(元素){
var caretofset=0;
var doc=element.ownerDocument | | element.document;
var win=doc.defaultView | | doc.parentWindow;
var-sel;
if(typeof win.getSelection!=“未定义”){
sel=win.getSelection();
如果(选择范围计数>0){
var range=win.getSelection().getRangeAt(0);
var precretange=range.cloneRange();
预重排列。选择节点内容(元素);
precretange.setEnd(range.endContainer,range.endOffset);
CareTofset=precretange.toString().length;
}
}如果((选择=文件选择)&&sel.type!=“控制”){
var textRange=sel.createRange();
var precarteTextRange=doc.body.createTextRange();
PrecretTextRange.moveToElementText(元素);
setEndPoint(“EndToEnd”,textRange);
CareTofset=PrecretTextRange.text.length;
}
返回caretofset;
}
函数setCaretPosition(元素,偏移){
var range=document.createRange();
var sel=window.getSelection();
//选择合适的节点
var currentNode=null;
var-previousNode=null;
对于(var i=0;i0){
currentNode=currentNode.childNodes[0];
}
//计算当前节点中的偏移量
if(previousNode!=null){
偏移量-=上一个节点的长度;
}
//检查当前节点是否有足够的长度
if(offset)尝试保存光标位置(请参见),然后在input.html(…)之后将其设置回(请参见)。我认为这里还有其他问题:在您的示例中是“突出显示”每次编辑文本时,word都将被包装在一个新的跨距中。在添加新跨距之前,您可能应该用占位符替换包装的word,然后再替换占位符。如果您有一个满足您期望的解决方案,您应该将其添加为答案并选择它。回到2016年。我为divs找到了一个很好的解决方案。并将其发布到此处回答这个问题:在您的特殊情况下,这是一个很好的解决方案:如果您在ContentDibales中禁用新行。否则,获取光标偏移量的脚本将忽略新行实体,如
,并将光标位置设置在错误的位置(在
元素之前)。当输入字符
时,还有一个ces。它会把整个内容弄乱。您可能应该先用
和
逃离第一个。此任务的代码太多了:(