gpt4 book ai didi

javascript - 在文本区域中模仿插入符号

转载 作者:数据小太阳 更新时间:2023-10-29 06:02:27 24 4
gpt4 key购买 nike

我试图模仿文本区域的插入符号,以创建一个非常轻量级的富文本区域。我不想使用 codemirror 之类的东西或任何其他大型库,因为我不会使用它们的任何功能。

我有一个 <pre>位于具有透明背景的文本区域后面,因此我可以模拟文本中的突出显示效果。但是,我也希望能够更改字体颜色(因此它并不总是相同的)。所以我尝试了 color: transparent在 textarea 上,它允许我以任何我想要的方式设置文本样式,因为它只出现在 <pre> 上文本区域后面的元素,但插入符号消失了。

虽然它并不完美,但我已经让它运行得相当好。主要问题是,当您按住一个键并向该字符发送垃圾邮件时,插入符号似乎总是落后一个字符。不仅如此,它似乎还占用大量资源......

如果您在代码中发现任何其他需要改进的地方,也请随时发表评论!

这是代码的 fiddle :http://jsfiddle.net/2t5pu/25/

对于出于任何原因不想访问 jsfiddle 的人,这里是完整的代码:

CSS:

textarea, #fake_area {
position: absolute;
margin: 0;
padding: 0;
height: 400px;
width: 600px;
font-size: 16px;
font: 16px "Courier New", Courier, monospace;
white-space: pre;
top: 0;
left: 0;
resize: none;
outline: 0;
border: 1px solid orange;
overflow: hidden;
word-break: break-word;
padding: 5px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
#fake_area {
/* hide */
opacity: 0;
}
#caret {
width: 1px;
height: 18px;
position: absolute;
background: #f00;
z-index: 100;
}

HTML:

<div id="fake_area"><span></span></div>
<div id="caret"></div>
<textarea id="textarea">test</textarea>

JavaScript:

var fake_area = document.getElementById("fake_area").firstChild;
var fake_caret = document.getElementById("caret");
var real_area = document.getElementById("textarea");

$("#textarea").on("input keydown keyup propertychange click", function () {
// Fill the clone with textarea content from start to the position of the caret.
// The replace /\n$/ is necessary to get position when cursor is at the beginning of empty new line.
doStuff();
});

var timeout;
function doStuff() {
if(timeout) clearTimeout(timeout);
timeout=setTimeout(function() {
fake_area.innerHTML = real_area.value.substring(0, getCaretPosition(real_area)).replace(/\n$/, '\n\u0001');
setCaretXY(fake_area, real_area, fake_caret, getPos("textarea"));
}, 10);
}


function getCaretPosition(el) {
if (el.selectionStart) return el.selectionStart;
else if (document.selection) {
//el.focus();
var r = document.selection.createRange();
if (r == null) return 0;

var re = el.createTextRange(), rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);

return rc.text.length;
}
return 0;
}

function setCaretXY(elem, real_element, caret, offset) {
var rects = elem.getClientRects();
var lastRect = rects[rects.length - 1];

var x = lastRect.left + lastRect.width - offset[0] + document.body.scrollLeft,
y = lastRect.top - real_element.scrollTop - offset[1] + document.body.scrollTop;

caret.style.cssText = "top: " + y + "px; left: " + x + "px";
//console.log(x, y, offset);
}

function getPos(e) {
e = document.getElementById(e);
var x = 0;
var y = 0;
while (e.offsetParent !== null){
x += e.offsetLeft;
y += e.offsetTop;
e = e.offsetParent;
}
return [x, y];
}

提前致谢!

最佳答案

难道一个可编辑的 Div 元素不能解决整个问题吗?

高亮代码:

http://jsfiddle.net/masbicudo/XYGgz/3/

var prevText = "";
var isHighlighting = false;
$("#textarea").bind("paste drop keypress input textInput DOMNodeInserted", function (e){
if (!isHighlighting)
{
var currentText = $(this).text();
if (currentText != prevText)
{
doSave();
isHighlighting = true;
$(this).html(currentText
.replace(/\bcolored\b/g, "<font color=\"red\">colored</font>")
.replace(/\bhighlighting\b/g, "<span style=\"background-color: yellow\">highlighting</span>"));
isHighlighting = false;
prevText = currentText;
doRestore();
}
}
});

不幸的是,这使得一些编辑功能丢失,例如 Ctrl + Z... 并且在粘贴文本时,插入符号停留在粘贴文本的开头。

我结合了其他答案的代码来生成此代码,所以请给予他们信任。

编辑:我发现了一些有趣的东西...如果您使用 contentEditable 元素,则会出现 native 插入符号,并且在其中使用另一个具有不可见字体的元素:

<div id="textarea" contenteditable style="color: red"><div style="color: transparent; background-color: transparent;">This is some hidden text.</div></div>

http://jsfiddle.net/masbicudo/qsRdg/4/

关于javascript - 在文本区域中模仿插入符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17526233/

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