首页 >web前端 >css教程 >创建一个支持语法高音代码的可编辑文本area

创建一个支持语法高音代码的可编辑文本area

Christopher Nolan
Christopher Nolan原创
2025-03-25 09:42:19362浏览

创建一个支持语法高音代码的可编辑文本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