1

I'm trying to figure out how to wrap each line of copy in a span. e.g if I have an element as follows:

.body-copy {
  position: relative;
  width: 100%;
  height: auto
}
<div class="body-copy">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est labour.
</div>

So the text fills the width of it's container, I need to wrap each line of copy in a span on document load, window load and window resize. If this is even possible? Any suggestions on this would be greatly appreciated!

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
user1374796
  • 1,544
  • 13
  • 46
  • 76
  • Where does line end? – Satpal Apr 03 '17 at 19:13
  • @Satpal _I need to wrap each line of copy in a span on document load, window load **and window resize**._ – Alon Eitan Apr 03 '17 at 19:14
  • 5
    What exactly are you trying to accomplish? HTML doesn't really acknowledge, except in very limited ways, the concept of a "line of [text]". – Jeff Zeitlin Apr 03 '17 at 19:15
  • I think the only practical way of doing this would be to wrap ***each word*** in a `span` and then with javascript figure out which `span`s belong to which row (by figuring out their positioning). Then do what you need to do to each one of those `span`s OR wrap them in another `span` with a class and apply the behavior to that class. – Chris Apr 03 '17 at 19:18
  • Related: http://stackoverflow.com/questions/118241/calculate-text-width-with-javascript (I already voted to close as too broad) – Alon Eitan Apr 03 '17 at 19:18
  • I think your question isn't entirely clear. You mean you want to get the rendered text, find a way to know where each rendered line of text ends and wrap each line in a span ? If it's that, I don't this it's possible. If not please explain better. – Nelson Teixeira Apr 03 '17 at 19:19
  • 4
    This could be an [X Y Problem](https://meta.stackexchange.com/a/66378) – DaniP Apr 03 '17 at 19:19
  • @NelsonTeixeira yes that's correct I need to know where each rendered line of text ends and wrap each line in a span, even on window resize too as I need to run a function on each span – user1374796 Apr 03 '17 at 19:21
  • Then it's not possible AFAIU. – Nelson Teixeira Apr 03 '17 at 19:22
  • Please refer to the link I post maybe describe your actual problem which kind of function ? what you really try to acomplish ? – DaniP Apr 03 '17 at 19:23

1 Answers1

0

Ok, so here is a messy, but functional way to do what you are asking. What this does is use a hidden div to measure the width against the original as we add words in one-by-one. Then, once the width threshold is reached, we create a new span element containing the words collected so far. Wash. Rinse. Repeat. Lastly, we scoop up the remaining words and add them to their own span, and replace the original text with our new HTML. You can use the wordWrap() function anytime the document loads or window resizes. I've added some borders to the span elements, just so you can easily see where the markup is being applied.

$(document).ready(function() {
  wordWrap();
});

function wordWrap() {
  var bdy = $(".body-copy");
  var text = $(bdy).text();
  var html = $(bdy).html();
  var bWidth = $(bdy).width();
  var words = text.split(" ");
  var span = "";
  var word = "";
  var allSpans = "";
  var lastWord = "";
  $(words).each(function(i, w) {
    if (lastWord != "") {
      w = lastWord + " "+ w ;
      lastWord = "";
    };
    word = w + " ";
    span = span + word;
    $(".body-copy-two").append(word);
    if ($(".body-copy-two").width() >= bWidth) {
      var wLen = word.length;
      span = span.slice(0, -wLen);
      lastWord = w + " ";
      allSpans = allSpans + "<span>" + $.trim(span) + "</span>";
      $(".body-copy-two").html("");
      span = "";
      word = "";
    }
  });
  var lastSpan = "<span>" + $(".body-copy-two").text() + "</span>";
  $(bdy).html(allSpans + lastSpan);
}
.body-copy {
  position: relative;
  width: 100%;
  height: auto
}

.body-copy-two {
  position: absolute;
  visibility: hidden;
}

.body-copy span {
  border: 1px solid black;
  display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="body-copy">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est labour.
</div>
<div class="body-copy-two"></div>
Dryden Long
  • 10,072
  • 2
  • 35
  • 47
  • @DrydenLang this is close, it doesn't work so well with a window resize though...which it will need also – user1374796 Apr 04 '17 at 09:06
  • @user1374796 You'll just need to call the function I posted inside of a window resize event handler like so: `$(window).on('resize', function(){wordWrap();});` – Dryden Long Apr 04 '17 at 13:05
  • @DrydenLang I did, it's incredibly buggy though and doesn't work well at all on resize! – user1374796 Apr 04 '17 at 13:15