首頁 >web前端 >css教學 >創建一個支持語法高音代碼的可編輯文本area

創建一個支持語法高音代碼的可編輯文本area

Christopher Nolan
Christopher Nolan原創
2025-03-25 09:42:19400瀏覽

創建一個支持語法高音代碼的可編輯文本area

當我正在研究一個需要編輯器組件的項目時,我真的希望一種方法讓編輯器突出顯示鍵入的語法。有類似的項目,例如Codemirror,Ace和Monaco,但它們都是重量重量,功能豐富的編輯,而不僅僅是我想要的語法強調的可編輯Textareas。

這花了一些罰款,但是我最終做出了一些可以完成這項工作的東西,並想分享我的工作方式,因為它涉及將流行的語法集成到HTML的編輯功能,以及一些有趣的邊緣案例以及一些有趣的案例。

繼續前進,在我們挖進去時旋轉!

建議之後,我還將其作為自定義元素在GitHub上發布,因此您可以快速將網頁中的組件用作單個元素。</code-input></p> <h3>問題</h3> <p>首先,我嘗試使用DIV上的可滿足屬性。我在DIV中鍵入了一些源代碼,並通過JavaScript在輸入上通過Prism.js(一種流行的語法熒光筆)進行了運行。似乎是一個體面的主意,對吧?我們有一個可以在前端進行編輯的元素,Prism.js將其語法樣式應用於元素中的鍵入內容。</p> <p>克里斯(Chris)涵蓋瞭如何在此視頻中使用Prism.js。</p> <p>但這是不做的。每次元素中的內容更改時,都會操縱DOM並將<strong>用戶的光標推回代碼的開始</strong>,這意味著源代碼向後出現,最後一個字符在開始,而第一個字符在末尾。</p> <p>接下來,我嘗試使用<textarea>,但這也不起作用,因為<strong>TextAreas只能包含純文本</strong>。換句話說,我們無法為已輸入的內容設計樣式。文本方面似乎是編輯文本而沒有不必要的錯誤的唯一方法 - 它不允許Prism.js做事。</textarea></p> <p>當源代碼包裹在典型的</p> <pre class="brush:php;toolbar:false"> &lt;code&gt;標籤組合中時,Prism.js的工作要好得多 - 僅缺少方程式的可編輯部分。&lt;p&gt;因此,似乎都不是獨自工作。但是,我想,&lt;em&gt;為什麼不呢?&lt;/em&gt;&lt;/p&gt; &lt;h3&gt;解決方案&lt;/h3&gt; &lt;p&gt;我在頁面上添加了語法高點&lt;/p&gt; &lt;pre class=&quot;brush:php;toolbar:false&quot;&gt; &lt;code&gt;&lt;em&gt;和&lt;/em&gt;textarea,並使用JavaScript函數使&lt;pre class=&quot;brush:php;toolbar:false&quot;&gt; &lt;code&gt;更改instut的Innertext內容。我還向&lt;pre class=&quot;brush:php;toolbar:false&quot;&gt; &lt;code&gt;結果添加了一個隱藏的屬性,以便屏幕讀取器只能讀取輸入的內容,而不是兩次大聲朗讀。&lt;pre rel=&quot;HTML&quot; data-line=&quot;&quot;&gt; &lt;textarea oninput=&quot;“&quot; update&gt; &lt;/textarea&gt; &lt;pre aria-hidden=&quot;“&quot; true&gt; &lt;code&gt; &lt;/code&gt; </pre></pre> <pre rel="JavaScript" data-line="">功能更新(文本){ 讓結果= document.queryselector(“#imainmighting-content”); //更新代碼 result_element.innertext = text; //語法亮點 prism.highlightelement(result_element); }</pre> <p>現在,當對文本方面進行編輯時 - 如在鍵盤上的一個按壓鍵返回 - 語法高點的代碼更改。我們將要遇到一些錯誤,但是我想首先專注於使其看起來像您直接編輯語法高光元素,而不是單獨的textarea。</p> <h3>使其像代碼編輯器一樣“感覺”</h3> <p>這個想法是明顯地將元素合併在一起,因此當實際上有兩個元素的元素時,似乎我們正在與一個元素進行交互。我們可以添加一些CSS,這些CS基本上允許<textarea>和<pre class="brush:php;toolbar:false"> &lt;code&gt;元素的尺寸和間隔。&lt;/code&gt;</pre></textarea></p> <pre rel="CSS" data-line=""> #編輯,#highlighting { / *這兩個元素都需要相同的文本和空間樣式,因此它們彼此直接在頂部 */ 保證金:10px; 填充:10px; 邊界:0; 寬度:計算(100%-32px); 身高:150px; } #編輯,#highlighting,#highlighting * { / *還添加文本樣式以突出顯示令牌 */ 字體大小:15pt; font-family:單域; 線高:20pt; }</pre> <p>然後,我們想將它們放在彼此的頂部:</p> <pre rel="CSS" data-line=""> #編輯,#highlighting { 位置:絕對; 頂部:0; 左:0; }</pre> <p>從那裡開始,z索引允許Textarea在前面堆放一個突出顯示的結果:</p> <pre rel="CSS" data-line=""> / *在結果的前面移動文本方面 */ #編輯{ z索引:1; } #highlighting { Z-Index:0; }</pre> <p>如果我們在這裡停下來,我們將看到第一個錯誤。看起來Prism.js並不強調語法,但這僅僅是因為文本方面掩蓋了結果。</p> <p>我們可以使用CSS解決此問題!<em>除了</em>Caret(光標)外,我們將使<textarea>完全透明:</textarea></p> <pre rel="CSS" data-line=""> / *使Textarea幾乎完全透明 */ #編輯{ 顏色:透明; 背景:透明; 商彩色:白色; / *或選擇您喜歡的顏色 */ }</pre> <p>啊,好多了!</p> <h3>更多修復!</h3> <p>一旦我走了這麼遠,我就會與編輯器一起玩,並能夠找到更多需要修復的東西。好處是,使用JavaScript,CSS甚至HTML,所有問題都很容易解決。</p> <h4>刪除本地拼寫檢查</h4> <p>我們正在製作代碼編輯器,並且代碼具有許多單詞和屬性,瀏覽器的本機咒語檢查器會認為是拼寫錯誤。</p> <p>拼寫檢查不是一件壞事。在這種情況下,這是無益的。標記不正確的原因是因為它拼寫不正確還是代碼無效?很難說。要解決此問題,我們只需要將<textarea>上的拼寫檢查屬性設置為false:</textarea></p> <pre rel="HTML" data-line=""> &lt;textarea spellcheck=&quot;“&quot; false ...&gt;&lt;/textarea&gt;</pre> <h4>處理新線條</h4> <p>事實證明,Innertext不支持Newlines(\ n)。</p> <p>需要編輯更新功能。我們可以使用InnerHTML,而不是使用Innertext,而是用&lt;替換開放的括號字符(</p> <pre rel="JavaScript" data-line=""> result_element.innerhtml = text.replace(new Regexp(“&”,“ g”),“&”)。替換(new Regexp(“ &lt;h4&gt;滾動和調整大小&lt;/h4&gt;&lt;p&gt;這是另一件事:進行編輯時,突出顯示的代碼無法滾動。當滾動文本方面時,突出顯示的代碼不會滾動。&lt;/p&gt;&lt;p&gt;首先,讓我們確保textarea和結果支持滾動:&lt;/p&gt;&lt;pre rel=&quot;CSS&quot; data-line=&quot;&quot;&gt; / *可以滾動 */ #編輯,#highlighting { 溢出:自動; 白色空間:pre; / *允許Textarea水平滾動 */ }</pre><p>然後,為了確保結果滾動<em>使用</em>Textarea,我們將更新HTML和JavaScript:</p><pre rel="HTML" data-line=""> &lt;textarea oninput=&quot;“&quot; update sync_scroll onscroll=&quot;“&quot;&gt; &lt;/textarea&gt;</pre><pre rel="JavaScript" data-line="">函數sync_scroll(element){ / *滾動結果到滾動坐標 - 與textarea同步 */ 讓Result_Element = Document.queryselector(“#突出顯示”); //獲取並設置X和Y result_element.scrolltop = element.scrolltop; result_element.scrollleft = element.scrollleft; }</pre><p>一些瀏覽器還允許調整文本方面的大小,但這意味著Textarea和結果可能會變成不同的大小。 CSS可以解決此問題嗎?當然可以。我們將簡單地禁用調整大小:</p><pre rel="CSS" data-line=""> / *在Textarea上沒有大小 */ #編輯{ 調整大小:無; }</pre><h4>最終新線</h4><p>感謝此評論指出了此錯誤。</p><p>現在,滾動幾乎總是同步的,但是仍然有<strong>一種情況仍然不起作用</strong>。當用戶創建新行時,在新行上輸入任何文本之前,光標和文本文本的文本<strong>暫時處於錯誤的位置</strong>。這是因為<strong>出於美學原因,<pre class="brush:php;toolbar:false"> &lt;code&gt;塊忽略了空的最後一行。&lt;/code&gt;</pre></strong>因為這是用於功能代碼輸入的,而不是顯示的代碼,因此需要顯示空的最終行。這是通過<strong>提供最終行內容來完成的,因此它不再為空</strong>,並且在更新功能中添加了幾行JavaScript。我使用了一個空間字符,因為<strong>用戶看不見</strong>。</p><pre rel="JavaScript" data-line="3-6">功能更新(文本){ 讓結果= document.queryselector(“#imainmighting-content”); //處理最終新線(請參閱文章) if(text [text.length-1] ==“ \ n”){//如果最後一個字符是newline字符 text =“”; //將佔位符空間字符添加到最後一行 } //更新代碼 result_element.innerhtml = text.replace(new Regexp(“&”,“ g”),“&”)。替換(new Regexp(“ &lt;h4&gt;縮進線&lt;/h4&gt;&lt;p&gt;要調整的較棘手的事情之一是如何處理結果中的線壓痕。當前設置編輯器的方式,帶空格的縮進線正常。但是,如果您比空間更喜歡標籤,那麼您可能已經註意到這些空間無法正常工作。&lt;/p&gt;&lt;p&gt; JavaScript可用於使&lt;kbd&gt;TAB&lt;/kbd&gt;鍵正確工作。我添加了評論,以清楚該功能中正在發生的事情。&lt;/p&gt;&lt;pre rel=&quot;HTML&quot; data-line=&quot;&quot;&gt; &lt;textarea ... onkeydown=&quot;“&quot; check_tab&gt; &lt;/textarea&gt;</pre><pre rel="JavaScript" data-line="">函數check_tab(元素,事件){ 令code = element.value; if(event.key ==“ tab”){ / * TAB鍵按 */ event.preventDefault(); //停止正常 讓tre tre_tab = code.slice(0,element.SelectionStart); //在選項卡之前的文字 令After_tab = code.slice(element.SelectionEnd,element.value.length); //在選項卡之後發短信 令Cursor_pos = element.SelectionEnd 1; //光標在選項卡之後移動的位置 - 以1個字符向前移動到after選項卡 element.value = tre_tab“ \ t” after_tab; //添加標籤char //移動光標 element.SelectionStart = Cursor_pos; element.SelectionEnd = cursor_pos; 更新(element.value); //更新文本以包含縮進 } }</pre><p>為了確保在<textarea>和語法高點密碼塊中的選項<strong>卡字符的大小相同</strong>,請編輯CSS以包含Tab-Size屬性:</textarea></p><pre rel="CSS" data-line="4"> #編輯,#highlighting,#highlighting * { / *還將文本樣式添加到高亮令牌 */ /* ETC。 */ tab-size:2; }</pre><h3>最終結果</h3><p>不太瘋狂,對吧?我們所擁有的只是<textarea>,<pre class="brush:php;toolbar:false">和&lt;code&gt; html中的元素,將它們堆疊在一起的新系列的CSS和一個語法突出顯示庫,以格式化所輸入的內容。我最喜歡的是,我們正在使用普通的語義HTML元素,利用本機屬性來獲得我們想要的行為,依靠CSS來產​​生一種幻覺,即我們只與一個元素進行交互,然後伸手求助於JavaScript來解決一些邊緣案例。&lt;/code&gt;</pre></textarea></p><p>當我使用Prism.js進行語法強調時,該技術將與其他人一起使用。如果您願意,它甚至可以與您創建的語法熒光筆一起使用。我希望這變得有用,並且可以在許多地方使用,無論是CMS的Wysiwyg編輯器,甚至是表格​​,其中輸入源代碼的能力是前端作業應用程序的要求還是測驗。畢竟,它是一個<textarea>,因此它能夠以任何形式使用 - 如果需要,您甚至可以添加佔位符!</textarea></p><p><strong>更新(2024年8月27日):</strong>讀者路易斯·洛博(Luis Lobo</p><h3>更新</h3></pre></pre> <ul><li> <strong>2025年1月13日:</strong>示例已更新了一個白色空間:pre;聲明在所有瀏覽器中平均處理空格,從而可以更好地進行水平滾動。</li></ul>

以上是創建一個支持語法高音代碼的可編輯文本area的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn