You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改代码实现用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>

关键修改说明

  1. 保留原始DOM结构:不再用textContent提取纯文本,而是直接克隆容器内的所有节点,完整保留<a>、<span>等标签。
  2. 动态测量行位置:通过临时插入节点获取元素的getBoundingClientRect()位置,判断是否触发换行,避免破坏原始内容。
  3. 灵活构建行结构:根据换行判断结果,动态创建.line-wrap和.line容器,将同一行的节点加入对应容器。
  4. CSS适配:将.line设为display: inline,保持文本的自然换行行为,避免强制块级元素破坏布局。

内容的提问来源于stack exchange,提问作者mrWilson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 05:03:11