user2272048
user2272048

Reputation:

How do I check if an element contains at least one direct text node

How do I check if an element contains at least one direct text node ?

Given:

<div id="a">
  One <span>Two</span>
</div>

<div id="b">
  <span>Three</span>
</div>

<div id="c">
  Four
</div>

<div id="d"> </div>

And:

function containsDirectText(el) {
  // using plain Javascript, not jQuery
}

Then:

containsDirectText(document.getElementById('a')) // should return true
containsDirectText(document.getElementById('b')) // should return false
containsDirectText(document.getElementById('c')) // should return true
containsDirectText(document.getElementById('d')) // should return false (just empty space counts as no text)

Upvotes: 2

Views: 810

Answers (1)

Stephen P
Stephen P

Reputation: 14820

You can check the nodeType of the child nodes to find text nodes, but your example "b" that you want to return false does have a text node — the spaces used to indent — so you have to exclude blank text nodes.

function containsDirectText(el) {
  return [...el.childNodes]
      .some(n => n.nodeType === Node.TEXT_NODE
            && n.nodeValue.trim() !== '');
}

console.log(
containsDirectText(document.getElementById('a')) // should return true
);

console.log(
containsDirectText(document.getElementById('b')) // should return false
);

console.log(
containsDirectText(document.getElementById('c')) // should return true
);

console.log(
containsDirectText(document.getElementById('original-d')) // should return false
);

console.log(
containsDirectText(document.getElementById('new-d')) // should return false
);
<div id="a">
  One <span>Two</span>
</div>

<div id="b">
  <span>Three</span>
</div>

<div id="c">
  Four
</div>

<div id="original-d"></div>

<div id="new-d"> </div>

(I split your "d" case into the original empty div and the updated div with only whitespace)

An element's childNodes returns a NodeList, so I use the spread operator to turn it into an Array, which has the .some(callback) method.

some returns true if the callback function returns a truthy value for at least one element in the array, so I test each element to see if its nodeType is a TEXT_NODE and that the nodeValue is not empty.

If at least one child node fits that description, some returns true so containsDirectText returns true.

Upvotes: 4

Related Questions