gpt4 book ai didi

javascript - 如何在包含许多 html 标签的内容可编辑的 div 中替换插入符号之前的自定义文本?

转载 作者:行者123 更新时间:2023-11-30 20:29:35 25 4
gpt4 key购买 nike

  var input = document.getElementById("div_id");
var username = "TEST";
input.focus();

var selection = window.getSelection();
var range = selection.getRangeAt(0);

var span = document.createElement('span');
span.setAttribute('class', 'tagged-user');
span.setAttribute('id', 55);
span.innerHTML = username;

//var initialText = input.textContent;
//var before_caret = initialText.slice(0,getCaretPosition(input));
// var after_caret = initialText.slice(getCaretPosition(input), initialText.length);
// // var before_caret = input.textContent;
// console.log("before_caret " + before_caret);
// *******************************
//this is the regex that match last @something before caret and it work good.
//var droped_at = before_caret.replace(/@\w+(?!.*@\w+)/g, '');
// *******************************

// input.textContent = droped_at + after_caret;
// console.log("before_caret " + before_caret);




range.deleteContents();
range.insertNode(span);

range.collapse(false);
range.insertNode(document.createTextNode("\u00a0"));
// cursor at the last
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
.tagged-user {
color: #1e81d6;
font-weight: bold;
}
<div contenteditable="true" id="div_id">
First person <span class="tagged-user" id="1">@Joe </span> and @te and <span class="tagged-user" id="2">@Emilie</span> want to go to the beach.
</div>

文本示例:你好,@te @emilie 你好吗?(@emilie 是一个 span 标签)在这个例子中,如果光标在@te 之后,我想用 TEST 替换 @te。

你好,

我正在尝试制作一个类似提及系统的 facebook。只要我输入“@”,我就能触发显示我所有联系人列表的消息。一切正常,唯一的问题是当我键入“@te”以在列表中查找“TEST”时,它应该能够用“TEST”替换“@te”。它输入@teTEST,知道怎么做吗?我正在使用带有 contenteditablediv

非常感谢。

最佳答案

在内容可编辑的 div 元素中获取/设置插入符位置似乎太复杂了。

无论如何,我用我在这些主题中找到的函数创建了一个工作片段......
Get caret position in contentEditable div
Set Caret Position in 'contenteditable' div that has children
…并添加了一个函数 oninput 来进行你想要的替换:
(有关更多详细信息,请参阅我的代码中的注释)

var input = document.getElementById("div_id");
var replaced = "@te"; // TAKIT: Added this variable
var replacer = "@TEST"; // TAKIT: Renamed this variable
var replacer_tags = ['<span class="tagged-user" id="0">', '</span>']; // TAKIT: Added after comment
input.focus();

// TAKIT: Added functions from these solutions:
// https://stackoverflow.com/questions/3972014/get-caret-position-in-contenteditable-div
function GetCaretPosition(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;
}

// https://stackoverflow.com/questions/36869503/set-caret-position-in-contenteditable-div-that-has-children
function SetCaretPosition(el, pos) {
// Loop through all child nodes
for (var node of el.childNodes) {
if (node.nodeType == 3) { // we have a text node
if (node.length >= pos) {
// finally add our range
var range = document.createRange(),
sel = window.getSelection();
range.setStart(node, pos);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
return -1; // we are done
} else {
pos -= node.length;
}
} else {
pos = SetCaretPosition(node, pos);
if (pos == -1) {
return -1; // no need to finish the for loop
}
}
}
return pos; // needed because of recursion stuff
}


// TAKIT: Added this whole function
input.oninput = function() {
var caretPos = GetCaretPosition(input); // Gets caret position
if (this.innerHTML.includes(replaced)) { // Filters the calling of the function
this.innerHTML = this.innerHTML.replace(replaced, replacer_tags.join(replacer) + '&nbsp;'); // Replace
caretPos += replacer.length - replaced.length + 1; // Offset due to strings length difference
SetCaretPosition(input, caretPos); // Restores caret position
}
// console.clear(); console.log(this.innerHTML); // For tests
}
.tagged-user {
color: #1e81d6;
font-weight: bold;
}
<div contenteditable="true" id="div_id">
First person <span class="tagged-user" id="1">@Joe</span> and (add "te" to test) @ and <span class="tagged-user" id="2">@Emilie</span> want to go to the beach.
</div>

希望对您有所帮助。

关于javascript - 如何在包含许多 html 标签的内容可编辑的 div 中替换插入符号之前的自定义文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50505203/

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