在carret位置之前删除最后x个字符

时间:2017-12-19 12:26:25

标签: javascript jquery contenteditable

简短版:

我有一个满足的div。我想在carret postion之前移除最后的x个字符。

长版:

如果有人在contenteditable div中键入[,则应显示一个自动提示列表,由ajax调用填充。这已经完成了。我也可以在carret位置插入所选的建议并添加]。但是,在添加建议之前,应删除已经由用户键入的字符。 括号[不仅仅是" trigger-char"但也是一种类似降价的格式元素。

示例:

div中的文字(" |"代表carret):Lorem ipsum| sit lorem ipsum dolor

用户现在键入[do以启动自动建议:Lorem ipsum [do| sit lorem ipsum dolor

建议

dolor并在carret:Lorem ipsum [do|dolor sit lorem ipsum dolor

之后插入

问题:在插入建议

之前,应删除所有已输入的字符do

所需行为:Lorem ipsum [dolor] sit lorem ipsum dolor

尝试解决方案:

Insert text at cursor in a content editable div - 工作但我无法删除最后的字符 https://developer.mozilla.org/en-US/docs/Web/API/Selection - 试图从MDN中获取一些想法,但不知道如何更改选择的textNode内容

代码:

提取最后一个" ["和carret在DB中搜索建议:

var sel = window.getSelection();
var cords = getCaretCoords();
var searchQuery = extractSearchQuery(sel.anchorNode.data, sel.anchorOffset, "[");

function extractSearchQuery(searchString, caretPos, triggerString) {
    //cut everything after carret
    searchString = searchString.slice(searchString.lastIndexOf(triggerString) + 1, caretPos);
    return searchString;
}

在carret之后插入建议:

function insertTextAtCursor(text) {
    var sel, range, html;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();
            var newTextNode = document.createTextNode(text);
            range.insertNode(newTextNode);
        }
    } else if (document.selection && document.selection.createRange) {
        document.selection.createRange().text = text;
    }
}

3 个答案:

答案 0 :(得分:1)

具有以下假设和定义:

  • 你知道" ["因为这会触发自动建议开始工作。我们称之为indexbracket
  • 您知道在自动建议时使用括号后输入的文字。我们称之为lookupstring

然后你应该用以下内容替换div的内容:

divtext = divtext.substring(0, indexbracket) + divtext.substring(indexbracket + lookupstring.length + 1);

示例:(其中我使用了不同的方法来查找indexbracket等,而不是您可能使用的)



var divtext = "Lorum ipsum [doAUTOSUGGESTEDTEXT sit";
var indexbracket = divtext.indexOf('[');
var lookupstring = "do";
divtext = divtext.substring(0, indexbracket) + divtext.substring(indexbracket+lookupstring.length+1);
console.log(divtext);




修改帖子后更新 鉴于您需要插入符号的位置,您可以选择"手动"更换文本后重置插入符号的位置,请在此处查看此优秀答案:https://stackoverflow.com/a/512542/3000771

答案 1 :(得分:0)

您已使用window.getSelection(),这是正确的。使用window.getSelection().baseOffset可以获得您所在的索引。从这里开始,如果您知道选择的位置与要替换的块的起始位置相比,您将能够计算其起始索引。您也知道长度,因此您需要获取内容的起始子字符串和结束子字符串(省略要替换的块)并在它们之间连接新内容。

答案 2 :(得分:0)

感谢所有建议。

我的解决方案现在与该答案类似:https://stackoverflow.com/a/11248187/8622487

var length = lookupstring.length; //length of the allready typed string
var sel = window.getSelection();
sel.collapseToStart();
for (var i = 0; i < length; i++) {
    sel.modify("move", "backward", "character");
}
for (var i = 0; i < length; i++) {
    sel.modify("extend", "forward", "character");
}

这将选择allready类型的字符。插入匹配关键字时会覆盖它。

我知道这很快,很脏,但它有效(在Firefox和Chrome中)