花潮论坛

搜索
热搜: 活动 交友 discuz
查看: 9|回复: 1

利用p标签的visibility属性给textarea加行号

[复制链接]
  • TA的每日心情
    奋斗
    2026-5-21 13:02
  • 签到天数: 1821 天

    [LV.Master]伴坛终老

    3224

    主题

    13万

    回帖

    28万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫相遇之美鹰傲苍穹花好月圆紫色情节飞龙在天王者至尊大将风范音画大师天籁妙音共看流星风雨同行我心永远幸福快乐喜乐安康侠骨柔肠心想事成开朗大方花潮管理

    发表于 2026-5-21 13:04 | 显示全部楼层 |阅读模式

    请马上登录,朋友们都在花潮里等着你哦:)

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x

    CSS的visibility属性极具兼容性:

    自 2015年7月 起,visibility 属性已在主流浏览器中得到支持,可在大多数设备和浏览器版本中正常使用。

    该属性显示或隐藏元素而不更改文档的布局。并且,当主元素通过该属性设置为隐藏时,其子元素可通过设置该属性为显示依然得到正常渲染。

    根据 visibility 上述特性,我们可以不再拐弯抹角地为 textarea 创建行号了,也无需处理软换行垂直占位问题。具体思路是:在一个父元素的规范下垂直叠加、左右略微错开的两个元素,按文档流顺序安排,一为 div,二为 textarea,二者创建相同的影响排版布局的核心CSS属性值。div 根据 textarea 的输入动态添加 p 标签,p 标签 visibility 设置为 hidden,::before 或 ::after 伪元素用来显示行号、设置 visibility 为 visible,这样行号可以完美实现,且通过浏览器的 Ctrl+F 组合键查找关键字时查找结果不会成倍统计,因为 visibility 设为 hidden 的元素其上的文本浏览器会直接忽略。到目前止,这样的思路网上还没有人提到过。

    说明:通过 visibility 设置 p 标签及其伪元素还有一个好处:可以不用特别定位伪元素,这种情形之下使用 ::before 伪元素比较自然,它将出现在 p 段落的开头处。当然,如果需要精准定位水平方向行号显示的位置,那么 p 标签及其伪元素应做定位管理。

    以下是实现代码:

    <style> /* 编辑器父元素 */ .ed-container { margin: 30px auto; width: 800px; height: 450px; border: 1px solid gray; background: linear-gradient(90deg, #ddd 50px, white 50px); padding: 0; position: relative; } /* 行号p标签类选择器及其伪元素(其父元素属性设置交给JS完成) */ .lnum { margin: 0; padding: 0; visibility: hidden; } .lnum::before { content: attr(data-num); width: 50px; color: #888; padding: 0; visibility: visible; } /* 编辑器 */ #editor { position: absolute; left: 50px; width: calc(100% - 50px); height: 100%; box-sizing: border-box; padding: 8px; font-size: 18px; background: #fff; border: none; outline: none; resize: none; } </style> <!-- 编辑器HTML结构,行号容器将由JS生成 --> <div class="ed-container"> <textarea id="editor"></textarea> </div> <script> // 函数:生成行号容器(参数 pa 是 textarea 的父元素) function createLnumBox(pa, textarea) { // 创建行号div元素 const lineNumberBox = document.createElement('div'); // 核心CSS属性 const keyProperties = [ 'font', 'line-height', 'padding', 'margin', 'overflow', 'width', 'height', 'white-space', 'word-break', 'overflow-wrap', 'box-sizing', 'position' ]; // 读取编辑器元素CSS属性 const computedStyle = window.getComputedStyle(textarea); // 将核心CSS属性复刻到行号容器 keyProperties.forEach(prop => { const value = computedStyle.getPropertyValue(prop); lineNumberBox.style[prop] = value; }); pa.prepend(lineNumberBox); // 行号容器加到 textarea 之前 return lineNumberBox; // 返回容器(便于后续操作) } // 函数:动态生成行号 function mkLineNum(textarea, lnumDiv) { lnumDiv.innerHTML = ''; // 清空行号容器内容 // 获取编辑器内容并按行拆分 const lines = textarea.value.split('\n'); const frg = new DocumentFragment(); // 创建文档碎片 // 每一行都生成p标签加入到行号容器中 lines.forEach((line, key) => { const p = document.createElement('p'); p.className = 'lnum'; // 使用CSS预设的类名 p.innerText = line ? line : '<br>'; // 空行使用换行标签(避免坍塌) p.dataset.num = key + 1; // p标签伪元素数据:行号 frg.appendChild(p); // p标签加入到文档碎片 }); lnumDiv.appendChild(frg); // 文档碎片加入到行号div容器 } const editor = document.getElementById('editor'); // 获取编辑器 const container = document.querySelector('.ed-container'); // 获取编辑器父元素 const lnum = createLnumBox(container, editor); // 创建行号容器 // 编辑器输入事件:触发行号生成 editor.addEventListener('input', (e) => { mkLineNum(editor, lnum); }); // 编辑器滚动事件:保持行号同步翻滚 editor.addEventListener('scroll', () => { lnum.scrollTop = editor.scrollTop; }); // 页面初始化时加行号 document.addEventListener('DOMContentLoaded', () => { mkLineNum(editor, lnum); }); </script>

    上述基于textarea的行号案例:

    • 当前字号下支持最多4位数的行号显示,多了需要调整编辑框左移和行号底色占位尺寸;
    • 适用于小型项目,处理一千行上下的代码应该无压力;
    • 行号div容器也可以在CSS和HTML中维护但不建议,尽量在JS中复刻以确保容器和编辑器两个元素的核心属性相一致;
    • 案例演示仅实现了核心行号功能,其它功能需要自行加入;
    • 若用于生产环境,建议对编辑器对象进行更完备的封装。

    评分

    参与人数 1威望 +30 金钱 +60 经验 +30 收起 理由
    梦江南 + 30 + 60 + 30 匠心独运,细节精致入微!

    查看全部评分

  • TA的每日心情
    开心
    2026-5-21 08:47
  • 签到天数: 726 天

    [LV.9]以坛为家II

    513

    主题

    2万

    回帖

    5万

    积分

    贵宾

    Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7

    花潮美女鼠牛虎兔龙蛇马羊猴鸡狗猪缤纷心情心曲飞扬花好月圆飞龙在天音画大师天籁妙音共看流星风雨同行我心永远喜乐安康花潮贵宾

    发表于 2026-5-21 13:14 | 显示全部楼层
    谢谢黑黑老师辛苦,学习了。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|手机版|Archiver|服务支持:DZ动力|huachaowang.com Inc. ( 蜀ICP备17032287号-1 )

    GMT+8, 2026-5-21 17:02 , Processed in 0.075778 second(s), 26 queries .

    Powered by Discuz! X3.4

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表