Als ich an einem Projekt arbeitete, das eine Editor-Komponente für Quellcode benötigte, wollte ich unbedingt eine Möglichkeit haben, die eingegebene Syntax im Editor hervorzuheben. Es gibt zwar Projekte dafür, wie z. B. CodeMirror, Ace und Monaco, aber das sind alles vollwertige, funktionsreiche Editoren, keine einfachen editierbaren Textareas mit Syntaxhervorhebung, wie ich es wollte.
Mit etwas Tüftelei gelang es mir, etwas zu entwickeln, das die Aufgabe erfüllt, und ich wollte teilen, wie ich es gemacht habe, da es die Integration einer beliebten Syntaxhervorhebungsbibliothek mit den Bearbeitungsfunktionen von HTML sowie einige interessante Randfälle zu berücksichtigen beinhaltet.

Probieren Sie es gleich aus, während wir tiefer eintauchen!
Nach einem Vorschlag habe ich dies auch als benutzerdefiniertes Element auf GitHub veröffentlicht, sodass Sie die Komponente schnell als einzelnes <code-input>-Element auf einer Webseite verwenden können.
Das Problem
Zuerst versuchte ich, das Attribut contenteditable in einem div zu verwenden. Ich tippte etwas Quellcode in das div und ließ ihn über JavaScript bei oninput durch Prism.js, einen beliebten Syntax-Hervorheber, laufen. Klingt nach einer guten Idee, oder? Wir haben ein Element, das im Frontend bearbeitet werden kann, und Prism.js wendet seine Syntaxstile auf das im Element eingegebene an.
Chris erklärt in diesem Video, wie man Prism.js verwendet.
Aber das war ein No-Go. Jedes Mal, wenn sich der Inhalt des Elements ändert, wird das DOM manipuliert und der Cursor des Benutzers wird zum Anfang des Codes zurückgesetzt, was bedeutet, dass der Quellcode rückwärts angezeigt wird, mit den letzten Zeichen am Anfang und den ersten Zeichen am Ende.

Als Nächstes versuchte ich es mit einer <textarea>, aber auch das funktionierte nicht, da Textareas nur einfachen Text enthalten können. Mit anderen Worten, wir können den eingegebenen Inhalt nicht gestalten. Eine textarea scheint der einzige Weg zu sein, den Text ohne unerwünschte Fehler zu bearbeiten – sie lässt Prism.js einfach nicht seine Arbeit tun.
Prism.js funktioniert wesentlich besser, wenn der Quellcode in einer typischen <pre><code>-Tag-Kombination eingeschlossen ist – es fehlt nur der bearbeitbare Teil der Gleichung.
Daher scheint keiner von beiden allein zu funktionieren. Aber ich dachte, *warum nicht beide?*
Die Lösung
Ich habe sowohl eine syntaxhervorgehobene <pre><code> *als auch* eine textarea zur Seite hinzugefügt und den innerText-Inhalt von <pre><code> per JavaScript über eine Funktion bei oninput ändern lassen. Ich habe auch ein aria-hidden-Attribut zum <pre><code>-Ergebnis hinzugefügt, damit Screenreader nur das eingeben, was in die <textarea> eingegeben wird, anstatt zweimal vorgelesen zu werden.
<textarea id="editing" oninput="update(this.value);"></textarea>
<pre id="highlighting" aria-hidden="true">
<code class="language-html" id="highlighting-content"></code>
</pre>
function update(text) {
let result_element = document.querySelector("#highlighting-content");
// Update code
result_element.innerText = text;
// Syntax Highlight
Prism.highlightElement(result_element);
}

Wenn die textarea bearbeitet wird – also eine Taste auf der Tastatur losgelassen wird –, ändert sich der syntaxhervorgehobene Code. Es gibt ein paar Fehler, zu denen wir noch kommen werden, aber ich möchte mich zuerst darauf konzentrieren, es so aussehen zu lassen, als würden Sie direkt das syntaxhervorgehobene Element bearbeiten, anstatt eine separate textarea.
Es soll sich wie ein Code-Editor anfühlen
Die Idee ist, die Elemente sichtbar zu verschmelzen, damit es so aussieht, als würden wir mit einem Element interagieren, obwohl tatsächlich zwei Elemente arbeiten. Wir können etwas CSS hinzufügen, das es der <textarea> und den <pre><code>-Elementen im Grunde erlaubt, konsistent in Größe und Abstand zu sein.
#editing, #highlighting {
/* Both elements need the same text and space styling so they are directly on top of each other */
margin: 10px;
padding: 10px;
border: 0;
width: calc(100% - 32px);
height: 150px;
}
#editing, #highlighting, #highlighting * {
/* Also add text styles to highlighting tokens */
font-size: 15pt;
font-family: monospace;
line-height: 20pt;
}
Dann wollen wir sie direkt übereinander positionieren
#editing, #highlighting {
position: absolute;
top: 0;
left: 0;
}
Von dort aus ermöglicht z-index, dass die textarea vor dem hervorgehobenen Ergebnis gestapelt wird
/* Move the textarea in front of the result */
#editing {
z-index: 1;
}
#highlighting {
z-index: 0;
}
Wenn wir hier aufhören, sehen wir unseren ersten Fehler. Es sieht nicht so aus, als würde Prism.js die Syntax hervorheben, aber das liegt nur daran, dass die textarea das Ergebnis verdeckt.

Das können wir mit CSS beheben! Wir machen die <textarea> komplett transparent, *außer* dem Caret (Cursor)
/* Make textarea almost completely transparent */
#editing {
color: transparent;
background: transparent;
caret-color: white; /* Or choose your favorite color */
}
Ah, viel besser!

Weitere Korrekturen!
Nachdem ich so weit gekommen war, spielte ich ein wenig mit dem Editor und konnte ein paar weitere Dinge finden, die behoben werden mussten. Das Gute ist, dass alle Probleme recht einfach mit JavaScript, CSS oder sogar HTML behoben werden können.
Native Rechtschreibprüfung entfernen
Wir erstellen einen Code-Editor, und Code hat viele Wörter und Attribute, die die native Rechtschreibprüfung eines Browsers als falsch geschriebene Wörter ansehen wird.

Rechtschreibprüfung ist nichts Schlechtes; sie ist in dieser Situation nur nicht hilfreich. Wird etwas als falsch markiert, weil es falsch geschrieben ist, oder weil der Code ungültig ist? Das ist schwer zu sagen. Um das zu beheben, müssen wir nur das Attribut spellcheck auf der <textarea> auf false setzen.
<textarea id="editing" spellcheck="false" ...>
Behandlung von Zeilenumbrüchen
Es stellt sich heraus, dass innerText keine Zeilenumbrüche (\n) unterstützt.

Die Funktion update muss bearbeitet werden. Anstatt innerText zu verwenden, können wir innerHTML verwenden, das offene Klammersymbol (<) durch < und das Ampersand-Zeichen (&) durch & ersetzen, um zu verhindern, dass HTML-Escapes ausgewertet werden. Dies verhindert, dass neue HTML-Tags erstellt werden, und ermöglicht die Anzeige des tatsächlichen Quellcodes anstelle des Versuchs des Browsers, den Code zu rendern.
result_element.innerHTML = text.replace(new RegExp("&", "g"), "&").replace(new RegExp("<", "g"), "<"); /* Global RegExp */

Scrollen und Größenänderung

Hier ist noch eine Sache: Der hervorgehobene Code kann während des Bearbeitens nicht scrollen. Und wenn die Textarea gescrollt wird, scrollt der hervorgehobene Code nicht mit.
Zuerst stellen wir sicher, dass sowohl die textarea als auch das Ergebnis das Scrollen unterstützen
/* Can be scrolled */
#editing, #highlighting {
overflow: auto;
white-space: nowrap; /* Allows textarea to scroll horizontally */
}
Dann, um sicherzustellen, dass das Ergebnis *mit* der Textarea scrollt, aktualisieren wir das HTML und JavaScript wie folgt
<textarea id="editing" oninput="update(this.value); sync_scroll(this);" onscroll="sync_scroll(this);"></textarea>
function sync_scroll(element) {
/* Scroll result to scroll coords of event - sync with textarea */
let result_element = document.querySelector("#highlighting");
// Get and set x and y
result_element.scrollTop = element.scrollTop;
result_element.scrollLeft = element.scrollLeft;
}
Einige Browser erlauben auch die Größenänderung einer textarea, aber das bedeutet, dass die textarea und das Ergebnis unterschiedliche Größen haben könnten. Kann CSS das beheben? Natürlich. Wir deaktivieren einfach die Größenänderung.
/* No resize on textarea */
#editing {
resize: none;
}
Abschließende Zeilenumbrüche

Dank dieses Kommentars, der auf diesen Fehler hingewiesen hat.
Nun ist das Scrollen fast immer synchronisiert, aber es gibt immer noch einen Fall, in dem es immer noch nicht funktioniert. Wenn der Benutzer eine neue Zeile erstellt, befinden sich der Cursor und der Text der Textarea vorübergehend in der falschen Position, bevor auf der neuen Zeile Text eingegeben wird. Das liegt daran, dass der <pre><code>-Block aus ästhetischen Gründen eine leere letzte Zeile ignoriert. Da dies für eine funktionale Code-Eingabe und nicht für angezeigten Code bestimmt ist, muss die leere letzte Zeile angezeigt werden. Dies geschieht, indem der letzten Zeile Inhalt gegeben wird, damit sie nicht mehr leer ist, mit ein paar Zeilen JavaScript, die zur Funktion update hinzugefügt werden. Ich habe ein Leerzeichen verwendet, weil es für den Benutzer unsichtbar ist.
function update(text) {
let result_element = document.querySelector("#highlighting-content");
// Handle final newlines (see article)
if(text[text.length-1] == "\n") { // If the last character is a newline character
text += " "; // Add a placeholder space character to the final line
}
// Update code
result_element.innerHTML = text.replace(new RegExp("&", "g"), "&").replace(new RegExp("<", "g"), "<"); /* Global RegExp */
// Syntax Highlight
Prism.highlightElement(result_element);
}
Zeilen einrücken
Eines der kniffligeren Dinge, die angepasst werden müssen, ist die Handhabung von Zeileneinrückungen im Ergebnis. So wie der Editor derzeit eingerichtet ist, funktioniert das Einrücken von Zeilen mit Leerzeichen gut. Aber wenn Sie Tabs mehr als Leerzeichen bevorzugen, haben Sie vielleicht bemerkt, dass diese nicht wie erwartet funktionieren.
JavaScript kann verwendet werden, um die Tab-Taste richtig funktionieren zu lassen. Ich habe Kommentare hinzugefügt, um klarzustellen, was in der Funktion geschieht.
<textarea ... onkeydown="check_tab(this, event);"></textarea>
function check_tab(element, event) {
let code = element.value;
if(event.key == "Tab") {
/* Tab key pressed */
event.preventDefault(); // stop normal
let before_tab = code.slice(0, element.selectionStart); // text before tab
let after_tab = code.slice(element.selectionEnd, element.value.length); // text after tab
let cursor_pos = element.selectionEnd + 1; // where cursor moves after tab - moving forward by 1 char to after tab
element.value = before_tab + "\t" + after_tab; // add tab char
// move cursor
element.selectionStart = cursor_pos;
element.selectionEnd = cursor_pos;
update(element.value); // Update text to include indent
}
}
Um sicherzustellen, dass die Tab-Zeichen die gleiche Größe haben, sowohl in der <textarea> als auch im syntaxhervorgehobenen Codeblock, bearbeiten Sie die CSS so, dass die tab-size-Eigenschaft enthalten ist.
#editing, #highlighting, #highlighting * {
/* Also add text styles to highlighing tokens */
[...]
tab-size: 2;
}
Das Endergebnis
Nicht zu verrückt, oder? Wir haben nur <textarea>, <pre> und <code>-Elemente im HTML, ein paar Zeilen CSS, die sie stapeln, und eine Syntaxhervorhebungsbibliothek, um das Eingegebene zu formatieren. Und was ich daran am besten mag, ist, dass wir mit normalen, semantischen HTML-Elementen arbeiten, native Attribute nutzen, um das gewünschte Verhalten zu erzielen, CSS verwenden, um die Illusion zu erzeugen, dass wir nur mit einem Element interagieren, und dann zu JavaScript greifen, um einige Randfälle zu lösen.
Obwohl ich Prism.js für die Syntaxhervorhebung verwendet habe, wird diese Technik auch mit anderen funktionieren. Sie würde sogar mit einer selbst erstellten Syntaxhervorhebung funktionieren, wenn Sie das möchten. Ich hoffe, dies wird nützlich und kann an vielen Stellen eingesetzt werden, sei es ein WYSIWYG-Editor für ein CMS oder sogar Formulare, bei denen die Möglichkeit, Quellcode einzugeben, eine Anforderung ist, wie bei einer Front-End-Bewerbung oder vielleicht einer Quizfrage. Es ist schließlich eine <textarea>, daher kann sie in jedem Formular verwendet werden – Sie können sogar ein placeholder hinzufügen, wenn Sie möchten!
Obwohl es das visuelle Erscheinungsbild beim Tippen von Code in einem Code-Editor mit der integrierten Syntaxhervorhebungsfunktion fast perfekt widerspiegelt, hat Ihre Version immer noch einige Fehler, z. B. wenn Sie
<,>oder&in die Textarea eingeben, werden stattdessen<,>und&angezeigt, anstatt des tatsächlichen Codes. Können Sie bitte auch dasinput-Ereignis anstelle deskeyup-Ereignisses verwenden? Dasinput-Ereignis aktualisiert die Hervorhebung sofort, währendkeyupeine ziemlich ärgerliche Verzögerung zwischen dem Tippen und dem Anzeigen der eingegebenen Zeichen verursacht.Das ist ein guter Punkt. Sie können die HTML-Escapes wie
&stoppen, indem Sie die Zeichenersetzungszeile JavaScript in derupdate-Funktion bearbeiten, um die&s zu ersetzen, wie unten gezeigt.Vielen Dank auch, dass Sie mich an das
input-Ereignis erinnern. Ich werde beide Änderungen zum CodePen-Demo hinzufügen.Sehr schöne Lösung, gefällt mir die Einrückungs-Umgehung
Das ist so fantastisch!
Ich habe CodeMirror für dasselbe verwendet und es scheint jetzt so übertrieben!
Das sollte TOTALLY ein Webkomponente wie
<code-editor>sein.Vielen Dank für diesen Kommentar; Sie haben mich inspiriert, ein
<code-input>-Custom-Element zu erstellen! Ich habe hier einen CodePen erstellt, und Sie können diesen Code gerne verwenden. Sie können ihn auf jeder Website verwenden, wenn Sie die JavaScript- und eine CSS-Datei für Prism.js importieren, da es Prism.js zum Funktionieren benötigt.Bitte beachten Sie, dass das Haupt-*"Funky"* Prism.js-CSS-Thema (ohne den hier behandelten bearbeitbaren Teil) von Lea Verou erstellt wurde, nicht von mir, wie die Kommentare im Code zeigen. Sie können ein anderes Thema wählen, indem Sie den Themen-Teil des CSS-Codes durch ein beliebiges Thema von der Prism.js-Website ersetzen.
Ich hoffe, das ist für Sie nützlich und ich hoffe, Sie genießen es!
Ich wollte nur kurz anmerken, dass dies eine fantastische Lektüre war. Ein so interessantes Problem, das es zu lösen gilt, und eine großartige Schritt-für-Schritt-Aufschlüsselung, wie Sie es geschafft haben.
Ich habe das auch schon mal bei Google Code gemacht, aber leider ist das Projekt eingestellt worden. Eigentlich können wir hier jeden JavaScript-Syntax-Hervorheber verwenden, und ich denke, ein Regex-basierter Syntax-Hervorheber ist für diesen Fall am besten geeignet, da wir den Syntax-Hervorheber bei jedem Tastendruck auf den gesamten Code anwenden müssen.
Also im Allgemeinen
Von
<textarea>Zeichen vor der Auswahl abrufen.
Zeichen in der Auswahl abrufen.
Zeichen nach der Auswahl abrufen.
Zum
<pre>-ElementDas bei jedem Tastendruck tun!
Das ist sehr ineffizient und Sie werden den Unterschied spüren, wenn Sie ein sehr großes Dokument öffnen.
Der Grund, warum CodeMirror, Ace, Monaco und dergleichen schneller arbeiten können, obwohl sie größeren Quellcode haben, ist, dass sie auf dem Stream arbeiten. Nur Teile, die im sichtbaren Bereich sind, werden hervorgehoben, jeglicher Text unter und über der Bildlaufleiste wird ignoriert.
Notizen
font-size,font-family,line-height,text-indentundletter-spacingin<textarea>und in<pre>müssen gleich sein.width,height,padding,margin,border-width,outlineundbox-sizingin<textarea>und in<pre>müssen gleich sein.Das ist großartig!
Indem ich mich von dieser Lösung inspirieren ließ, konnte ich mich von der absoluten Positionierung und der synchronisierten Scrollfunktion lösen. Dank der Grid-Anzeige können Sie die Textbox und die hervorgehobene Anzeige perfekt überlagern und die Textbox dehnt sich aus, um die Größe des Pre-Elements anzunehmen.
HTML
CSS
JS
Meine Hervorhebungsfunktion fügt … in das Pre-Element ein und manchmal ist die Überlagerung nicht gut (ohne die Spans funktioniert es gut, aber ich habe keine Hervorhebung mehr). Haben Sie eine Idee, wie ich mein Problem lösen kann? Ich schätze, das tritt manchmal auch bei Ihrer Lösung auf.
Danke :)
Ich mag, wie Sie CSS Grid verwenden, um die Elemente zu überlagern. Ich verstehe das Problem, das Sie gefunden haben, jedoch nicht vollständig. Ich denke, es könnte mit meiner Antwort an Thomas zusammenhängen, aber wenn nicht, erläutern Sie bitte die Art des Problems, und ich werde so schnell wie möglich antworten.
Versuchen Sie zu tippen, bis der Überlauf des Divs aktiviert ist, und Sie werden das erste Problem sehen, das Sie ignoriert haben.
Vielen Dank, dass Sie darauf hingewiesen haben. Dieser Fehler kann leicht behoben werden, indem die CSS-Eigenschaft
white-space: nowrapsowohl für die Elemente#editingals auch für#highlightinggesetzt wird, um der<textarea>das horizontale Scrollen zu ermöglichen. Ich habe dies zum Beitrag hinzugefügt und auch einen Code-Snippet unten angefügt.Danke!
Und ist es möglich, es mit pre-wrap zu verwenden, um die Scrollbar zu deaktivieren?
Ich konnte den Teil mit den neuen Zeilen nicht verstehen, was hat diese
result_element.innerHTML = text.replace(new RegExp("<", "g"), "<");mit neuen Zeilen zu tun?Da ich
innerHTMLanstelle voninnerTextverwende (das keine Zeilenumbrüche unterstützt), werden neue Zeilen angezeigt. Da es in einem<pre>-Element platziert ist und<pre>-Elemente neue Zeilen aus dem HTML anzeigen, ohne dass<br/>verwendet werden muss, werden die neuen Zeilen im<pre><code>-Block angezeigt. Die von Ihnen erwähnte Codezeile escapet die HTML-Tags, damit der Browser sie als Text behandelt und nicht als HTML, das in Elemente geparst wird, und hat nichts mit Zeilenumbrüchen zu tun.Ich habe den Artikel aktualisiert, um dies klarer zu machen.
Es scheint, dass die Notion-App div contentEditable verwendet und es funktioniert gut… wundere mich, wie das behoben werden kann…
Wirklich interessanter Artikel und Technik.
Zuerst hätte ich sicherlich nicht in Betracht gezogen, sowohl textarea als auch ein
<pre>-Element zu kombinieren, und stattdessen mit einem contenteditable gekämpft :)Ich denke, die Handhabung von Zeilenumbrüchen kann eleganter gelöst werden, indem
textContentanstelle voninnerTextverwendet wird, da es Zeilenumbrüche\nunterstützt.Wenn die neue Zeile unten leer ist. Die Ausrichtung in der Textarea und
<pre>sind um 1 Zeile falsch ausgerichtet. Das Beispiel hat auch dieses Problem. Wie behebt man das?Sie können dies mit JavaScript beheben, wie ich hier im Artikel erklärt habe. Vielen Dank, dass Sie auf diesen Fehler hingewiesen haben!
Hallo,
Nachdem der Code in der Textarea in die Datenbank übermittelt wurde, wird es ein Problem geben oder nicht?
Wird er so ausgegeben, wie ich ihn in die MySQL-Datenbank eingebe?
Z.B.
Ich habe das mit der Bild-Einbettung versucht, aber es gibt einen Bildfehler, anstatt den Code für die eingebettete Bildanzeige anzuzeigen.
Vielen Dank für Ihre Frage zur Integration mit dem Backend; es scheint etwas zu sein, über das ich beim Schreiben des Artikels nicht genug nachgedacht habe. Es scheint, dass Sie versehentlich den HTML-Code parsen, anstatt ihn in den
valuezu legen. Ich habe unten den Link zu einer Demo hinzugefügt, die zeigt, wie diese Backend-Integration funktioniert.Nochmals vielen Dank.
Wenn ich eine Zeile mit Tabs aus Notepad kopiere, bricht es.
Zum Beispiel: „ 1 2 3“
Versuchen Sie, dies zu kopieren und einzufügen und Strg+A zu drücken, und Sie werden sehen, dass Bearbeitung und Hervorhebung nicht übereinstimmen.
Wie behebt man das?
Vielen Dank, dass Sie mich über diesen Fehler informiert haben. Die Lösung besteht darin, die Eigenschaft
tab-sizefür die<textarea>und denpre code-Block gleich zu machen. Ich habe den Artikel aktualisiert, um dies detaillierter aufzunehmen.Wenn die Tabulatortaste gedrückt wird, während eine Auswahl aktiv ist, springt der Cursor genau um den ausgewählten Betrag nach vorne.
Dieser Fehler kann behoben werden, indem ersetzt wird
by
innerhalb der Funktion
check_tabDanke dafür!
Ich frage mich, ob ich dumm bin, aber ich bekomme keines der Codepen-Beispiele zum Laufen – ich kann Text in den weißen Pseudo-Textareas auswählen und auf Links darin klicken, aber ich kann keinen Cursor erscheinen lassen, um etwas zu tippen. Ich habe es in Safari 15.1 und Firefox 94.0.1 auf macOS Big Sur und Safari auf iPadOS 15.1 ausprobiert.
Firefox 95.0
Der sichtbare Cursor bleibt in der ersten Zeile. Er ist leider unbrauchbar.
Damit es in Firefox funktioniert, verwenden Sie
auf #editing und #highlighting.
In Firefox hat das Setzen von
whitespaceaufpre-wrapbei mir nicht funktioniert, aberpreschon.auf #editing, #highlighting und #highlighting code
Das ist großartig. Ich habe damit einen Python-Editor erstellt. ㅆVielen Dank
Um die Textarea zu speichern und erneut zu bearbeiten, wird der Textcode nicht farbig. Sie müssen auf die Textarea klicken und auf Ihrer Tastatur tippen, damit die Farbe wirksam wird. Kann die Farbe angewendet werden, ohne dass die Tastatur funktioniert?
Es scheint, dass Prism.js zwar alle
pre code-Elemente automatisch hervorhebt, bei highlight.js müssten Sie die Funktionupdate(),hljs.highlightElement([pre code element]), initial mit dem Element ausführen. Sie könnten auchhljs.highlightAll()einmal verwenden. Dies wird auf diesem CodePen-Pen demonstriert.Entschuldigung für die späte Antwort.
Tolle Sache, danke fürs Teilen! Ich lerne gerade erst HTML/CSS/JS, daher kann ich das noch nicht wirklich implementieren, aber ich verstehe das Wesen dieser Lösung und das ist eine wirklich coole Idee.
Hallo!! Das ist eine erstaunliche Übung!! Ich habe einige Probleme, ich werde hier fragen, falls jemand mit demselben Problem kämpft…
Das Problem, das ich habe, ist, dass beide Scrollbalken unterschiedlich sind, sobald ich eine neue Zeile am Ende hinzufüge. Die Sache ist, sobald ich eine neue Zeile hinzufüge und bevor ich einen Buchstaben schreibe, ist die Scrollbar der Textarea höher, weil der Hervorheber sie noch nicht hinzufügt, bis etwas geschrieben ist, und ich weiß nicht, was ich tun soll.
Irgendwelche Hilfe dabei?
Danke!
Ich antworte mir selbst, da die Antwort bereits in den Informationen des Beitrags steht… ABER!
Aber in meinem Fall hat jetzt jede Zeile ein Leerzeichen als erstes Zeichen, sodass jedes Mal, wenn ich eine neue Zeile hinzufüge, ein Leerzeichen eingefügt wird, und das ist nicht gut.
Warum passiert das bei Ihnen nicht?
Nochmals vielen Dank!
Ich entschuldige mich sehr für die Verzögerung; danke, dass Sie das erwähnt haben.
Ihre Situation deutet darauf hin, dass Sie möglicherweise
" "an dentextarea-Wert anhängen, anstatt an die temporäre Variable (die in diesem Artikel alstextbezeichnet wird) für den impre codeanzuzeigenden Text. Ich hoffe, das ist hilfreich; wenn nicht, lassen Sie es mich bitte wissen.Ich möchte, dass mein editierbarer Bereich beim Tippen auf der x-Achse scrollt.
Wie kann ich das tun?
(Entschuldigung für die späte Antwort; ich war in den letzten Wochen ziemlich beschäftigt.)
Die aktuelle Demo unterstützt bereits das Scrollen in beiden Achsen (siehe Scrolling and Resizing), sobald eine Textzeile länger wird als die Eingabebreite.
Um sicherzustellen, dass das code-input-Element nicht zu groß wird, was Probleme verursachen könnte, stellen Sie bitte sicher, dass Sie die Breite (was auch immer Sie wollen) -32px eingestellt haben.
Ich hoffe, das löst Ihr Problem; bitte lassen Sie mich wissen, wenn nicht.
Hallo Oliver Geer, es gibt ein Problem mit diesem Codebeispiel: Immer wenn ich Code über die Highlight-Methode einfüge und auch die Update-Methode (hervorgehobener Inhalt von
<code>) aufrufe, um denselben im Textfeld zu aktualisieren, nimmt der Code zu diesem Zeitpunkt automatisch Platz auf der linken Seite ein. Ich weiß nicht, wie ich das beheben kann.(Es tut mir leid, dass ich das eine Weile nicht bemerkt habe.)
Es scheint, dass Sie in diesem Szenario auch die Einrückung zusammen mit dem Code kopieren, sodass ein scheinbar leerer Bereich links erscheint. Sie könnten dies manuell löschen oder mehr JS verwenden, um die minimale Einrückung für jede Zeile des eingefügten Codes zu ermitteln und dann diesen Leerraum am Anfang jeder Zeile zu löschen.
Ich hoffe, das ist nützlich.
Das
onpaste-Ereignis (MDN-Link) sollte Ihnen helfen, Code auszulösen, wenn Text eingefügt wird, und den eingefügten Code zu erhalten.Aus Neugier, wie würden Sie
check_taberweitern, um die Einrückung des gesamten ausgewählten Textes zu ermöglichen? Im Moment führt die Auswahl mehrerer Zeilen dazu, dass die Auswahl durch einen einzigen Tab ersetzt wird.Sie könnten eine JavaScript-Logik verwenden, um Zeilen zu identifizieren (
element.value.split("\n")), dann in einer Schleife* Einrücken hinzufügen / entfernen (wenn Shift gehalten wird)
* Außerdem berechnen, wohin
selectionStartundselectionEndbasierend auf diesen Einrückungen verschoben werden sollenEs ist erwähnenswert, dass ich eine **viel** anpassbarere Version davon in einer benutzerdefinierten JavaScript-Bibliothek namens
code-inputauf GitHub und den Code, nach dem Sie fragen, imindent-Plugin gestellt habe. Wenn Sie diese Komponente in einem Projekt verwenden möchten, empfehle ich die Verwendung der Bibliothek – sie ist vollständig Open Source und wird gepflegt und ist so konzipiert, dass Sie nur die gewünschten Funktionen behalten können. Dieser Artikel ist eine gute Einführung in die Grundlagen (und stammt aus der Zeit vor der Bibliothek), aber die Bibliothek hat viele weitere Funktionen.