目录
问题
解决方案
使其像代码编辑器一样“感觉”
更多修复!
删除本地拼写检查
处理新线条
滚动和调整大小
最终新线
缩进线
最终结果
更新
首页 web前端 css教程 创建一个支持语法高音代码的可编辑文本area

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

Mar 25, 2025 am 09:42 AM

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

当我正在研究一个需要编辑器组件的项目时,我真的希望一种方法让编辑器突出显示键入的语法。有类似的项目,例如Codemirror,Ace和Monaco,但它们都是重量重量,功能丰富的编辑,而不仅仅是我想要的语法强调的可编辑Textareas。

这花了一些罚款,但是我最终做出了一些可以完成这项工作的东西,并想分享我的工作方式,因为它涉及将流行的语法集成到HTML的编辑功能,以及一些有趣的边缘案例以及一些有趣的案例。

继续前进,在我们挖进去时旋转!

建议之后,我还将其作为自定义元素在GitHub上发布,因此您可以快速将网页中的组件用作单个元素。</code-input></p> <h3 id="问题">问题</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> <div class="code" style="position:relative; padding:0px; margin:0px;"><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 id=&quot;解决方案&quot;&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><div class="contentsignin">登录后复制</div></div></pre> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre rel="JavaScript" data-line="">功能更新(文本){ 让结果= document.queryselector(“#imainmighting-content”); //更新代码 result_element.innertext = text; //语法亮点 prism.highlightelement(result_element); }</pre><div class="contentsignin">登录后复制</div></div> <p>现在,当对文本方面进行编辑时 - 如在键盘上的一个按压键返回 - 语法高点的代码更改。我们将要遇到一些错误,但是我想首先专注于使其看起来像您直接编辑语法高光元素,而不是单独的textarea。</p> <h3 id="使其像代码编辑器一样-感觉">使其像代码编辑器一样“感觉”</h3> <p>这个想法是明显地将元素合并在一起,因此当实际上有两个元素的元素时,似乎我们正在与一个元素进行交互。我们可以添加一些CSS,这些CS基本上允许<textarea>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> &lt;code&gt;元素的尺寸和间隔。&lt;/code&gt;</pre><div class="contentsignin">登录后复制</div></div></textarea></p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre rel="CSS" data-line=""> #编辑,#highlighting { / *这两个元素都需要相同的文本和空间样式,因此它们彼此直接在顶部 */ 保证金:10px; 填充:10px; 边界:0; 宽度:计算(100%-32px); 身高:150px; } #编辑,#highlighting,#highlighting * { / *还添加文本样式以突出显示令牌 */ 字体大小:15pt; font-family:单域; 线高:20pt; }</pre><div class="contentsignin">登录后复制</div></div> <p>然后,我们想将它们放在彼此的顶部:</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre rel="CSS" data-line=""> #编辑,#highlighting { 位置:绝对; 顶部:0; 左:0; }</pre><div class="contentsignin">登录后复制</div></div> <p>从那里开始,z索引允许Textarea在前面堆放一个突出显示的结果:</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre rel="CSS" data-line=""> / *在结果的前面移动文本方面 */ #编辑{ z索引:1; } #highlighting { Z-Index:0; }</pre><div class="contentsignin">登录后复制</div></div> <p>如果我们在这里停下来,我们将看到第一个错误。看起来Prism.js并不强调语法,但这仅仅是因为文本方面掩盖了结果。</p> <p>我们可以使用CSS解决此问题!<em>除了</em>Caret(光标)外,我们将使<textarea>完全透明:</textarea></p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre rel="CSS" data-line=""> / *使Textarea几乎完全透明 */ #编辑{ 颜色:透明; 背景:透明; 商彩色:白色; / *或选择您喜欢的颜色 */ }</pre><div class="contentsignin">登录后复制</div></div> <p>啊,好多了!</p> <h3 id="更多修复">更多修复!</h3> <p>一旦我走了这么远,我就会与编辑器一起玩,并能够找到更多需要修复的东西。好处是,使用JavaScript,CSS甚至HTML,所有问题都很容易解决。</p> <h4 id="删除本地拼写检查">删除本地拼写检查</h4> <p>我们正在制作代码编辑器,并且代码具有许多单词和属性,浏览器的本机咒语检查器会认为是拼写错误。</p> <p>拼写检查不是一件坏事。在这种情况下,这是无益的。标记不正确的原因是因为它拼写不正确还是代码无效?很难说。要解决此问题,我们只需要将<textarea>上的拼写检查属性设置为false:</textarea></p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre rel="HTML" data-line=""> &lt;textarea spellcheck=&quot;“&quot; false ...&gt;&lt;/textarea&gt;</pre><div class="contentsignin">登录后复制</div></div> <h4 id="处理新线条">处理新线条</h4> <p>事实证明,Innertext不支持Newlines(\ n)。</p> <p>需要编辑更新功能。我们可以使用InnerHTML,而不是使用Innertext,而是用&lt;替换开放的括号字符(</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre rel="JavaScript" data-line=""> result_element.innerhtml = text.replace(new Regexp(“&”,“ g”),“&”)。替换(new Regexp(“ &lt;h4 id=&quot;滚动和调整大小&quot;&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><div class="contentsignin">登录后复制</div></div><p>然后,为了确保结果滚动<em>使用</em>Textarea,我们将更新HTML和JavaScript:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre rel="HTML" data-line=""> &lt;textarea oninput=&quot;“&quot; update sync_scroll onscroll=&quot;“&quot;&gt; &lt;/textarea&gt;</pre><div class="contentsignin">登录后复制</div></div><div class="code" style="position:relative; padding:0px; margin:0px;"><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><div class="contentsignin">登录后复制</div></div><p>一些浏览器还允许调整文本方面的大小,但这意味着Textarea和结果可能会变成不同的大小。 CSS可以解决此问题吗?当然可以。我们将简单地禁用调整大小:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre rel="CSS" data-line=""> / *在Textarea上没有大小 */ #编辑{ 调整大小:无; }</pre><div class="contentsignin">登录后复制</div></div><h4 id="最终新线">最终新线</h4><p>感谢此评论指出了此错误。</p><p>现在,滚动几乎总是同步的,但是仍然有<strong>一种情况仍然不起作用</strong>。当用户创建新行时,在新行上输入任何文本之前,光标和文本文本的文本<strong>暂时处于错误的位置</strong>。这是因为<strong>出于美学原因,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"> &lt;code&gt;块忽略了空的最后一行。&lt;/code&gt;</pre><div class="contentsignin">登录后复制</div></div></strong>因为这是用于功能代码输入的,而不是显示的代码,因此需要显示空的最终行。这是通过<strong>提供最终行内容来完成的,因此它不再为空</strong>,并且在更新功能中添加了几行JavaScript。我使用了一个空间字符,因为<strong>用户看不见</strong>。</p><div class="code" style="position:relative; padding:0px; margin:0px;"><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 id=&quot;缩进线&quot;&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><div class="contentsignin">登录后复制</div></div><div class="code" style="position:relative; padding:0px; margin:0px;"><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><div class="contentsignin">登录后复制</div></div><p>为了确保在<textarea>和语法高点密码块中的选项<strong>卡字符的大小相同</strong>,请编辑CSS以包含Tab-Size属性:</textarea></p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre rel="CSS" data-line="4"> #编辑,#highlighting,#highlighting * { / *还将文本样式添加到高亮令牌 */ /* ETC。 */ tab-size:2; }</pre><div class="contentsignin">登录后复制</div></div><h3 id="最终结果">最终结果</h3><p>不太疯狂,对吧?我们所拥有的只是<textarea>,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">和&lt;code&gt; html中的元素,将它们堆叠在一起的新系列的CSS和一个语法突出显示库,以格式化所输入的内容。我最喜欢的是,我们正在使用普通的语义HTML元素,利用本机属性来获得我们想要的行为,依靠CSS来产​​生一种幻觉,即我们只与一个元素进行交互,然后伸手求助于JavaScript来解决一些边缘案例。&lt;/code&gt;</pre><div class="contentsignin">登录后复制</div></div></textarea></p><p>当我使用Prism.js进行语法强调时,该技术将与其他人一起使用。如果您愿意,它甚至可以与您创建的语法荧光笔一起使用。我希望这变得有用,并且可以在许多地方使用,无论是CMS的Wysiwyg编辑器,甚至是表格​​,其中输入源代码的能力是前端作业应用程序的要求还是测验。毕竟,它是一个<textarea>,因此它能够以任何形式使用 - 如果需要,您甚至可以添加占位符!</textarea></p><p><strong>更新(2024年8月27日):</strong>读者路易斯·洛博(Luis Lobo</p><h3 id="更新">更新</h3></pre></pre> <ul><li> <strong>2025年1月13日:</strong>示例已更新了一个白色空间:pre;声明在所有浏览器中平均处理空格,从而可以更好地进行水平滚动。</li></ul>

以上是创建一个支持语法高音代码的可编辑文本area的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1672
14
CakePHP 教程
1428
52
Laravel 教程
1332
25
PHP教程
1276
29
C# 教程
1256
24
静态表单提供商的比较 静态表单提供商的比较 Apr 16, 2025 am 11:20 AM

让我们尝试在这里造成一个术语:“静态表单提供商”。你带上html

使Sass更快的概念证明 使Sass更快的概念证明 Apr 16, 2025 am 10:38 AM

在一个新项目开始时,Sass汇编发生在眼睛的眨眼中。感觉很棒,尤其是当它与browsersync配对时,它重新加载

每周平台新闻:HTML加载属性,主要的ARIA规格以及从iframe转移到Shadow dom 每周平台新闻:HTML加载属性,主要的ARIA规格以及从iframe转移到Shadow dom Apr 17, 2025 am 10:55 AM

在本周的平台新闻综述中,Chrome引入了一个用于加载的新属性,Web开发人员的可访问性规范以及BBC Move

带有HTML对话框元素的一些动手 带有HTML对话框元素的一些动手 Apr 16, 2025 am 11:33 AM

这是我第一次查看HTML元素。我已经意识到了一段时间,但是尚未将其旋转。它很酷,

纸张形式 纸张形式 Apr 16, 2025 am 11:24 AM

购买或建造是技术的经典辩论。自己构建东西可能会感觉更便宜,因为您的信用卡账单上没有订单项,但是

'订阅播客”链接应在哪里? '订阅播客”链接应在哪里? Apr 16, 2025 pm 12:04 PM

有一段时间,iTunes是播客中的大狗,因此,如果您将“订阅播客”链接到喜欢:

托管您自己的非JavaScript分析的选项 托管您自己的非JavaScript分析的选项 Apr 15, 2025 am 11:09 AM

有很多分析平台可帮助您跟踪网站上的访问者和使用数据。也许最著名的是Google Analytics(广泛使用)

See all articles