如何修改代码实现用div包裹每行文本时保留HTML标签?
保留HTML标签的文本行包裹方案
原代码可以将文本每行用div包裹,但会丢失<a>、<span>等HTML标签——问题根源是使用了textContent提取内容,彻底破坏了原始DOM结构。以下是修改后的方案,既能按行包裹div,又能完整保留所有HTML标签:
修改后的完整代码
JavaScript
// 保留HTML标签的行包裹函数 function splitLines(container) { // 保存原始所有节点,避免直接修改时丢失结构 const originalNodes = Array.from(container.childNodes); container.innerHTML = ''; let currentLine = document.createElement('div'); currentLine.className = 'line'; let lineWrap = document.createElement('div'); lineWrap.className = 'line-wrap'; lineWrap.appendChild(currentLine); container.appendChild(lineWrap); let lastTop = null; originalNodes.forEach(node => { // 过滤空文本节点 if (node.nodeType === Node.TEXT_NODE) { const trimmedText = node.textContent.trim(); if (!trimmedText) return; } // 临时插入节点获取位置(不破坏原有结构) container.appendChild(node); const rect = node.getBoundingClientRect(); container.removeChild(node); // 判断是否触发换行 if (lastTop !== null && rect.top > lastTop) { // 新建行包裹结构 lineWrap = document.createElement('div'); lineWrap.className = 'line-wrap'; currentLine = document.createElement('div'); currentLine.className = 'line'; lineWrap.appendChild(currentLine); container.appendChild(lineWrap); } currentLine.appendChild(node); lastTop = rect.top; }); } // 调用行包裹函数 splitLines(document.querySelector('.wrap-lines')); /* 动画逻辑 */ const buttonTimeline = gsap.from(".line", { duration: 0.5, yPercent: 100, stagger: 0.2, clearProps: "all", paused: true }); document.querySelector(".btn-lines").addEventListener("click", () => { buttonTimeline.restart(); });
CSS
body { padding: 5% 10%; line-height: 1.2; } .container { max-width: 1400px; margin: 0 auto; } h1 { font-size: 24px; } p { font-size: 21px; } p span { background-color: red; color: white; } .line-wrap { display: block; overflow: hidden; margin: 0; padding: 0; } .line { display: inline; /* 保持文本自然换行特性 */ }
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://unpkg.com/gsap@3/dist/gsap.min.js"></script> <div class="container"> <!-- 带行包裹(HTML标签正常生效) --> <h1>带行包裹(HTML标签正常生效)</h1> <p class="wrap-lines">Lorem ipsum dolor sit, amet <a href="#">consectetur</a> adipisicing elit. Animi dolorem quasi aut dolore porro <span>iusto in facilis</span>, molestias nostrum possimus ipsum laboriosam dolorum voluptatibus praesentium consequuntur! Culpa quas nisi hic.</p> <button class="btn-lines">触发动画</button> <br> <br> <!-- 不带行包裹(HTML标签正常生效) --> <h1>不带行包裹(HTML标签正常生效)</h1> <p>Lorem ipsum dolor sit, amet <a href="#">consectetur</a> adipisicing elit. Animi dolorem quasi aut dolore porro <span>iusto in facilis</span>, molestias nostrum possimus ipsum laboriosam dolorum voluptatibus praesentium consequuntur! Culpa quas nisi hic.</p> </div>
关键修改说明
- 保留原始DOM结构:不再用
textContent提取纯文本,而是直接克隆容器内的所有节点,完整保留<a>、<span>等标签。 - 动态测量行位置:通过临时插入节点获取元素的
getBoundingClientRect()位置,判断是否触发换行,避免破坏原始内容。 - 灵活构建行结构:根据换行判断结果,动态创建
.line-wrap和.line容器,将同一行的节点加入对应容器。 - CSS适配:将
.line设为display: inline,保持文本的自然换行行为,避免强制块级元素破坏布局。
内容的提问来源于stack exchange,提问作者mrWilson
相关产品推荐
相关产品推荐

