skip to Main Content

I’m seeking assistance regarding a code I have. It wraps each line of text with a div tag. However, the issue is that it doesn’t account for HTML tags such as <a> or <span>. I’m struggling to figure out how to modify it to preserve these HTML tags within the text. Any help would be greatly appreciated, as I haven’t been able to solve this on my own.

// Wrapping lines
function splitLines(container, opentag, closingtag) {
  let $lines = container.children,
    $top = 0,
    $tmp = "";
  container.innerHTML = container.textContent.replace(/S+/g, "<n>$&</n>");
  for (let i = 0; i < $lines.length; i++) {
    let $rect = $lines[i].getBoundingClientRect().top;
    if ($top < $rect) $tmp += closingtag + opentag;
    $top = $rect;
    $tmp += $lines[i].textContent + " ";
  }
  container.innerHTML = $tmp += closingtag;
}

splitLines( $(".wrap-lines")[0], '<div class="line-wrap"><div class="line">', "</div></div>" );


/* Button */
let $button = gsap.from(".line", { duration: 0.5, yPercent: 100, stagger: 0.2, clearProps:"all" });
$(".btn-lines").on("click", function() {
  $button.restart();
});
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: inline-flex;
  overflow: hidden;
}
<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">
  
  <!-- With wrapping lines -->
  <h1>With wrapping lines (HTML tags don't work)</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">Animate Lines</button>
  
  <br>
  <br>

  <!-- Without wrapping lines -->
  <h1>Without wrapping lines (HTML tags work)</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>

2

Answers


  1. Use $lines[i].outerHTML instead of $lines[i].textContent so you get the entire HTML of the tag, not just its text.

    $(".wrap-lines").each(function () {
      let $lineWrapper = this;
      
      function splitLines(container, opentag, closingtag) {
        let $lines = container.children,
          $top = 0,
          $tmp = "";
        for (let i = 0; i < $lines.length; i++) {
          let $rect = $lines[i].getBoundingClientRect().top;
          if ($top < $rect) $tmp += closingtag + opentag;
          $top = $rect;
          $tmp += $lines[i].outerHTML + " ";
        }
        container.innerHTML = $tmp += closingtag;
      }
    
      //splitLines( $(this)[0], '<div class="line">', "</div>" );
    
    });
    p {
      font-size: 24px;
    }
    p span {
      background-color: red;
      color: white;
    }
    
    .line:hover {
      background-color: #eee;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <h1>Wrapping text lines</h1>
    
    <p class="wrap-lines">Lorem ipsum dolor sit, amet <a href="">consectetur</a> adipisicing elit. Animi dolorem quasi aut dolore <span>porro iusto</span> in facilis, molestias nostrum possimus ipsum laboriosam dolorum voluptatibus praesentium consequuntur! Culpa quas nisi hic.</p>
    Login or Signup to reply.
  2. The issue you’re facing stems from the fact that when you replace the text content with HTML tags, it loses the existing HTML structure.

    Updated (5.23pm IST)

    function splitLines(container, opentag, closingtag) {
      let lines = container.innerHTML.split('n');
      container.innerHTML = lines
        .map(line => line.trim() !== "" ? opentag + line + closingtag : "")
        .join('');
    }
    
    splitLines($(".wrap-lines")[0], '<div class="line-wrap"><div class="line">', "</div></div>");
    
    /* Button */
    let $button = gsap.from(".line", { duration: 0.5, yPercent: 100, stagger: 0.2, clearProps:"all" });
    $(".btn-lines").on("click", function() {
      $button.restart();
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search