首页 自动驾驶

TextArea 行号轻松搞定:前端技巧与性能优化实践

分类:自动驾驶
字数: (1767)
阅读: (4342)
内容摘要:TextArea 行号轻松搞定:前端技巧与性能优化实践,

在前端开发中,经常会遇到需要在 textarea 左侧添加行号的需求。例如,代码编辑器、日志展示等场景。直接使用原生 HTML 属性无法实现,需要借助 CSS 和 JavaScript 来模拟实现。本文将深入探讨实现原理,并提供多种解决方案,以及实战中的避坑经验。

实现原理深度剖析

实现 textarea 左侧添加行号的核心思路是:创建一个与 textarea 高度和滚动同步的容器,在该容器内生成行号。可以使用两种主要方式:

TextArea 行号轻松搞定:前端技巧与性能优化实践
  1. 双层 div 模拟:

    TextArea 行号轻松搞定:前端技巧与性能优化实践
    • 外层 div 作为容器,设置 overflow: hidden;,内部包含两个 div,一个用于显示行号,另一个是 textarea
    • 通过 JavaScript 同步两个 div 的滚动事件。
  2. pre 元素与 textarea 并排:

    TextArea 行号轻松搞定:前端技巧与性能优化实践
    • 使用 <pre> 元素模拟行号显示区域,并与 textarea 水平排列。
    • 监听 textarea 的输入事件,动态更新 <pre> 中的行号。
    • 同样需要 JavaScript 同步滚动。

这两种方法都涉及 DOM 操作和事件监听,需要注意性能优化,避免频繁操作导致页面卡顿。特别是在处理大量文本时,可以使用虚拟 DOM 或节流/防抖等技术。

TextArea 行号轻松搞定:前端技巧与性能优化实践

代码/配置解决方案

以下提供一个基于双层 div 模拟的解决方案:

HTML 结构

<div class="container">
  <div class="line-numbers"></div>
  <textarea class="code-input"></textarea>
</div>

CSS 样式

.container {
  display: flex;
  border: 1px solid #ccc;
  overflow: hidden; /* 隐藏滚动条 */
}

.line-numbers {
  width: 30px;
  background-color: #f0f0f0;
  text-align: right;
  padding: 5px;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap; /* 保留空白符和换行 */
  user-select: none; /* 禁止选中行号 */
}

.code-input {
  flex: 1;
  padding: 5px;
  font-size: 14px;
  line-height: 1.5;
  border: none;
  outline: none;
  resize: none; /* 禁止调整大小 */
  overflow: auto; /* 允许内部滚动 */
}

JavaScript 代码

const container = document.querySelector('.container');
const lineNumbers = document.querySelector('.line-numbers');
const codeInput = document.querySelector('.code-input');

// 初始化行号
function updateLineNumbers() {
  const lines = codeInput.value.split('\n').length;
  let numbers = '';
  for (let i = 1; i <= lines; i++) {
    numbers += i + '\n';
  }
  lineNumbers.textContent = numbers;
}

// 同步滚动
container.addEventListener('scroll', () => {
  lineNumbers.scrollTop = codeInput.scrollTop; // 或者 container.scrollTop,取决于滚动发生在哪个元素上
});

// 监听输入事件
codeInput.addEventListener('input', updateLineNumbers);

// 初始调用
updateLineNumbers();

使用 pre 元素

<div class="container">
  <pre class="line-numbers"></pre>
  <textarea class="code-input"></textarea>
</div>
.container {
  display: flex;
}

.line-numbers {
  width: 30px;
  background-color: #f0f0f0;
  text-align: right;
  padding: 5px;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap; /* 重要:保留空白和换行 */
  overflow: hidden; /* 隐藏滚动条 */
  user-select: none; /* 禁止选择行号 */
}

.code-input {
  flex: 1;
  padding: 5px;
  font-size: 14px;
  line-height: 1.5;
  border: none;
  outline: none;
  resize: none; /* 禁止调整大小 */
  overflow: auto; /* 允许滚动 */
  white-space: pre-wrap; /* 重要:保留空白和换行 */
}
const container = document.querySelector('.container');
const lineNumbers = document.querySelector('.line-numbers');
const codeInput = document.querySelector('.code-input');

function updateLineNumbers() {
  const lines = codeInput.value.split('\n').length;
  let numbers = '';
  for (let i = 1; i <= lines; i++) {
    numbers += i + '\n';
  }
  lineNumbers.textContent = numbers;
}

codeInput.addEventListener('input', updateLineNumbers);
container.addEventListener('scroll', () => {
    lineNumbers.scrollTop = codeInput.scrollTop;
});

updateLineNumbers();

实战避坑经验总结

  1. 性能优化:
    • 避免频繁 DOM 操作,使用 requestAnimationFrame 优化更新频率。
    • 对于大型文本,考虑使用虚拟 DOM 或懒加载行号。
    • 使用节流或防抖函数处理 scrollinput 事件。
  2. 样式同步:
    • 确保 textarea 和行号容器的字体、行高、内边距等样式一致,避免出现错位。
    • 需要考虑不同浏览器的兼容性问题,特别是滚动条样式。
  3. 空格与换行:
    • white-space: pre-wrap 非常重要,它能让 <pre> 标签正确显示空格和换行,保证行号与文本内容对齐。
  4. 文本对齐:
    • box-sizing: border-box 避免因为padding造成的宽度计算问题。
  5. 滚动同步:
    • 使用container.addEventListener('scroll', ...)监听容器的滚动事件,避免由于浏览器差异导致的滚动条位置不一致问题。

通过上述方法,可以有效地在 textarea 左侧添加行号,提升用户体验。在实际应用中,需要根据具体场景选择合适的方案,并注意性能优化和兼容性问题。

TextArea 行号轻松搞定:前端技巧与性能优化实践

转载请注明出处: 代码一只喵

本文的链接地址: http://m.acea1.store/blog/214314.SHTML

本文最后 发布于2026-04-25 01:50:59,已经过了3天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 躺平青年 21 小时前
    感觉用 Monaco Editor 或者 CodeMirror 这种现成的组件更省事啊,除非有特殊定制需求。
  • 北京炸酱面 5 天前
    感谢分享,用 pre 标签实现确实更简洁,学习了!
  • 草莓味少女 5 天前
    这个方案很实用,解决了我在代码编辑器开发中遇到的行号显示问题!
  • 舔狗日记 6 天前
    感谢分享,用 pre 标签实现确实更简洁,学习了!
  • 格子衫青年 1 小时前
    请问如果 textarea 内容很多,行号更新的时候会不会卡顿?有什么优化建议吗?