extra newline in innerText of BR followed by DIV

Viewed 454

If I have a DIV containing children including a BR followed by a DIV, the innerText value seems to have an extraneous newline. Moreover, if I then set div.innerText = div.innerText, the extra newline appears where it did not before!

I'm using Chrome. I have not tried with other browsers.

Is this a bug or a feature? I sure cannot conceive of any reason this would be by design. In any case, is there any way to get rid of this behavior?

The reason I'm trying to avoid this behavior is that I would like to collapse all of the DIV children into a single text node, but without changing (or at least without appearing to change) the actual text content inside the div. Avoiding DIV and BR elements inside the DIV is not an option.

The only way I have found so far to be able to get innerText which can be re-assigned back to div.innerText without changing the newlines is to create my own getInnerText() function which walks the node tree to find all BR and TEXT_NODE nodes while constructing a custom innerText piece by piece, all the while skipping newlines for DIV elements in the case where that element was immediately preceded by BR. It works, but it feels like there should be a much easier solution.

Example 1

The below example initially displays the following, as expected. Notice there is no space between the two lines:

enter image description here

However, if I then execute the following javascript:

div.innerText = div.innerText;

it unexpectedly inserts a blank newline!

enter image description here

window.setTimeout(function() {
  alert('Click ok to run\n  div.innerText = div.innerText\nwhich will unexpectedly insert an extra newline!');
  div.innerText = div.innerText;
}, 1500);
<div id=div>
  <span>abc</span>
  <br>
  <div>def</div>
</div>

Example 2

Here is a more complex example, including a block of 2 newlines (desired) which changes to a block of 3 newlines (not desired). Here's how it displays (properly):

enter image description here

and here's what it incorrectly changes to after setting innerText to itself:

enter image description here

window.setTimeout(function() {
  alert('Click ok to run\n  div.innerText = div.innerText\nwhich will unexpectedly insert two extra newlines!');
  div.innerText = div.innerText;
}, 1500);
<div id=div style="white-space:pre"><span>abc</span><br><div><span>   def</span><br><br><div>ghi</div.</div></div>

1 Answers

This seems by design.

You could collapse excess lines into a single linebreak

function read(element) {
  return element.innerText.replace(/\n+\s*\n+/g, "\n")
}

Or collapse all excess whitespace into a single space

function read(element) {
  return element.innerText.replace(/\s+/g, " ")
}
Related