Ich versuche, die caret eines Textbereich zum Zwecke der Schaffung eines sehr leichten Rich-Textfeld zu imitieren. Ich möchte nicht so etwas wie Codemirror oder irgendeine andere massive Bibliothek verwenden, weil ich keines ihrer Features verwenden werde.Mimicng caret in ein Textfeld
Ich habe eine <pre>
hinter einem Textarea mit einem transparenten Hintergrund positioniert, so dass ich einen Hervorhebungseffekt im Text simulieren kann. Ich möchte aber auch die Schriftfarbe ändern können (also nicht immer die gleiche). So versuchte ich color: transparent
auf der Textarea, die mir erlaubt, den Text in irgendeiner Weise zu gestalten, die ich will, weil es nur auf dem <pre>
Element hinter dem Textarea erscheint, aber das Caret verschwindet.
ich habe es bekommen ziemlich gut zu funktionieren, obwohl es nicht perfekt ist. Das Hauptproblem ist, dass, wenn Sie einen Schlüssel gedrückt halten und diesen Charakter spammen, der Caret immer um einen Charakter zurückbleibt. Nicht nur das, es scheint recht zu ressourcen schwer ..
Wenn Sie irgendwelche anderen Dinge im Code sehen, die verbessert werden müssen, fühlen Sie sich frei auf diesem zu kommentieren!
Hier ist eine Geige mit dem Code ist: http://jsfiddle.net/2t5pu/25/
Und für Sie, die nicht wollen aus irgendeinem Grund zu besuchen jsfiddle, hier ist der gesamte Code:
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];
}
Vielen Dank im Voraus!
Ihre caret hinkt aufgrund realen caret für ein wenig repiod Zeit apearing. Versuchen Sie, einige Zeilen Text einzugeben, und klicken Sie dann mit der linken Maustaste auf eine andere Zeile und halten Sie sie gedrückt, um sie zu sehen. Um dies zu überwinden, müssen Sie die Deckkraft des Textbereichs auf 0 setzen. Aber dann müssen Sie sich damit befassen, Text korrekt anzuzeigen. – twil
müssen Sie den Cursor wirklich 100 Mal pro Sekunde aktualisieren? Ich würde denken, 5 oder 10 würde ausreichen. es ist, warum Ihre Anwendung langsam ... – dandavis
@dandavis ausgeführt wird: muss man so reagieren, als Standard sein. –