4

<div style="width:30px;word-break:break-word">
some
</div>
<div>
</div>
<div style="width:10px;word-break:break-word">
words
</div>
<div style="width:50px;word-break:break-word">
wordswo大佬123words
</div>

There are some words in a div box styled width.

These words wraps by css word break rule.

Is there any way to convert them to a string split with \n or can we know a char in which line?

In the demo, the 'some' should be 'so\nme', the 'word' should be 'w\no\nr\nd\ns', the 'wordswowords' should be 'words\nwo大\n佬\n 123wo\nrds'

If all is english,it seems simple. But with Chinese, the result becomes difficult to understand.

chickenDinner
  • 129
  • 1
  • 5
  • 2
    Please create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve). – 31piy Aug 02 '18 at 08:34
  • 1
    Do you need to align visual representation of that string (given the width is arbitrary) with its logical representation - in other words, split the string exactly as it's shown? This doesn't look like a straight task: one possible approach involves looping through possible ranges and their ClientRects. May I ask why do you need this, what's the goal behind? – raina77ow Aug 02 '18 at 08:38
  • @raina77ow I create a dom input to let user input something, then move these text to a canvas. – chickenDinner Aug 02 '18 at 09:03

3 Answers3

2

One possible approach involves 'rolling range'. You move it through the textNode, checking the points where its height changes. Like this:

function getWordsByLines(textNode) {
  const words = [];

  const textLength = textNode.data.length;
  const range = textNode.parentNode.ownerDocument.createRange();
  range.selectNodeContents(textNode);

  let prevHeight = NaN;
  let prevWord = '';
  let rangeEnd = 0;
  while (rangeEnd <= textLength) {
    range.setEnd(textNode, rangeEnd);
    const box = range.getBoundingClientRect();
    if (prevHeight < box.height) {
      words.push(prevWord);
      prevHeight = NaN;
      prevWord = '';
      range.setStart(textNode, rangeEnd - 1);
    }
    else {
      prevWord = range.toString();
      prevHeight = box.height;
      rangeEnd++;
    }
  }
  if (prevWord !== '') { 
    words.push(prevWord); 
  };
  return words;
}

console.log(
  getWordsByLines(document.getElementById('a').childNodes[0])
);
console.log(
  getWordsByLines(document.getElementById('b').childNodes[0])
);
console.log(
  getWordsByLines(document.getElementById('c').childNodes[0])
);
<div id="a" style="width:30px;word-break:break-word">
some
</div>
<div id="b" style="width:10px;word-break:break-word">
words
</div>
<div id="c" style="width:50px;word-break:break-word">
wordswo大佬123words
</div>

You may or may not strip the leading and trailing EOL characters; I left them for the solution to be more universal. )

raina77ow
  • 103,633
  • 15
  • 192
  • 229
  • And here's [JSFiddle demo](http://jsfiddle.net/79g31dhx/) - sorry SO guys, but using snippet was really cumbersome for this task. :( – raina77ow Aug 02 '18 at 10:47
1

html:

<div class="oneWordOneLine">
  some words
</div>

css:

.oneWordOneLine {
  word-spacing: 999999px;
}

or you can also use word-spacing: 100vw;

if you have an element with fixed width you can just put as value for word-spacing the exact width of the element itself:

.oneWordOneLine {
   width: 100px;
   word-spacing: 100px;
 }
rvandoni
  • 3,297
  • 4
  • 32
  • 46
-1

Missed the point of the question I suppose, so here is a fix from another post asking exactly the same thing

And here is that same question from 7 years ago


Old Answer

add id

<div id="myDiv" style="width:10px">
  some words
</div>

then in javascript

let myTxt = document.getElementById("myDiv").innerHTML;

Now you can use regular expression or other string methods to change myTxt however you like then to put it back in, simply:

document.getElementById("myDiv").innerHTML = myTxt;

Some ideas that may help you:

  • Use regex to make new line /\n/
  • Use regex or indexOf() to find where something is.
  • Create array based on linebreaks .split("\n"), or compare .indexOf("\n")
Jensei
  • 450
  • 1
  • 4
  • 17
  • 3
    How does this answer OP's question? – Chris Satchell Aug 02 '18 at 08:44
  • The question is quite broad and the key question is "Is there any way to convert them?" By saving the text to a variable, then manipulating it, then putting it back we do exactly that. I further give ideas as to which methods to use in order to solve the 2 problems Op wants to solve. – Jensei Aug 02 '18 at 08:51
  • 1
    @Jensei But a text node styled with `word-wrap` is still the same text node. There wont be new line characters in it unless they are in it without the style too. Therefore your answer is no use to the OP. – Mark Baijens Aug 02 '18 at 08:53
  • To my understanding, OP wants to figure what words are on which line when the container uses word-wrap. Your answer doesn't properly reflect this – Chris Satchell Aug 02 '18 at 08:56
  • You are right, I missed the point of wordwrap. But the question is really a duplicate then. I updated the question with a link to when this question was previously asked. Once you have the line breaks in javascript it's trivial to find out which words are on each line using the "some ideas that may help you" part of my answer. I'm just trying to be helpful here. No reason to hate. – Jensei Aug 02 '18 at 09:07