gpt4 book ai didi

javascript - Rangy 在 contenteditable div 的退格键上失去了插入符号位置

转载 作者:行者123 更新时间:2023-11-30 18:27:08 37 4
gpt4 key购买 nike

我已经研究了所有 Rangy 问答几天,但无法适应这种情况。

我有以下内容可编辑

<div id="area" style="width:100%;height:2em;" 
contentEditable="true";
onkeyup="formatText();"
></div>

调用一个函数,每次用户键入内容时,它都会解析内容并格式化特定标记。

 function formatText() {

var el = document.getElementById('area');
var savedSel = saveSelection(el); // calls Rangy function

var tokenColor;

// removes html tags before passing the expression to the parser
var userInput = document.getElementById('area').innerHTML.replace(/(<([^>]+)>)/g,"").replace(/&amp;/g, "").replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/<span[^>]*>+<\/span>/, "");


var i, newHTML=[];

tokenType=[]; // [NUMBER,+,(,NUMBER,..]
tokenArray=[]; // [3,+,(5,...]

var resultOutput = parse(userInput); // parser also fills tokenType and tokenArray

for (i=0; i<tokenArray.length-1; i++){

newHTML += "<span style='color: " + tokenColor + " '>" + tokenArray[i] + "</span>";

} // newHTML looks like <span style='color: red'>3</span><span style='color: black'>+</span> etc.


el.innerHTML = newHTML; // replaces content of <div> with formatted text

restoreSelection(el, savedSel); // calls Rangy function to restore cursor position
}

我使用了作者在本论坛其他帖子中提供的以下基于 Rangy 的函数:

    function saveSelection(containerEl) {
var charIndex = 0, start = 0, end = 0, foundStart = false, stop = {};
var sel = rangy.getSelection(), range;

function traverseTextNodes(node, range) {
if (node.nodeType == 3) {
if (!foundStart && node == range.startContainer) {
start = charIndex + range.startOffset;
foundStart = true;
}

if (foundStart && node == range.endContainer) {
end = charIndex + range.endOffset;
throw stop;
}
charIndex += node.length;


} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
traverseTextNodes(node.childNodes[i], range);
}
}
}

if (sel.rangeCount) {
try {
traverseTextNodes(containerEl, sel.getRangeAt(0));
} catch (ex) {
if (ex != stop) {
throw ex;
}
}
}

return {
start: start,
end: end
};
}



function restoreSelection(containerEl, savedSel) {
var charIndex = 0, range = rangy.createRange(), foundStart = false, stop = {};
range.collapseToPoint(containerEl, 0);

function traverseTextNodes(node) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
range.setEnd(node, savedSel.end - charIndex);
throw stop;
}
charIndex = nextCharIndex;
}

else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
traverseTextNodes(node.childNodes[i]);
}
}
}

try {
traverseTextNodes(containerEl);
} catch (ex) {
if (ex == stop) {
rangy.getSelection().setSingleRange(range);
} else {
throw ex;
}
}
}

一切正常,直到我尝试删除一个 Angular 色。此时,光标会跳到 div 的开头。

知道为什么会发生这种情况吗?

非常感谢。

最佳答案

在 Tim Down 的帮助下我已经解决了这个问题(感谢 Tim!)。

他最近将新的 TextRange 模块添加到 Rangy 中,并且运行良好。该模块具有基于页面可见文本中字符索引的选择保存/恢复,因此不受 innerHTML 更改的影响。您可以在此处找到演示:

http://rangy.googlecode.com/svn/trunk/demos/textrange.html

文档(初步):http://code.google.com/p/rangy/wiki/TextRangeModule

所以基本上代码应该是:

    document.getElementById("area").onkeyup = function() {
var sel = rangy.getSelection();
var savedSel = sel.saveCharacterRanges(this);

var userInput = this.textContent || this.innerText;

var userInputLength = userInput.length;
var newHTML = [];

for (var i=0; i<userInputLength; i++) {
newHTML[i] = "<span style='color: red'>" + userInput.charAt(i) + "</span>";
}

this.innerHTML = newHTML.join("");

sel.restoreCharacterRanges(this, savedSel);
};

希望这对您有所帮助。

关于javascript - Rangy 在 contenteditable div 的退格键上失去了插入符号位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10557874/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com