8

I am getting the child nodes of en element and i want to check if the tags can actually contain text. For example:

<br />, <img />

Should return false and

<span></span>, <div></div>, <li></li>

should return true. Thanks!

isherwood
  • 58,414
  • 16
  • 114
  • 157
Ood
  • 1,445
  • 4
  • 23
  • 43
  • 2
    What about ` – Quentin Feb 26 '14 at 15:40
  • Any element that can contain text in any form or way, so also – Ood Feb 26 '14 at 15:42
  • You could check whether `el.childNodes.length > 0`, but generally there is no difference between an empty and a self-closing element in the DOM – Bergi Feb 26 '14 at 15:50

4 Answers4

9

Unfortunately, there is no way to detect how a tag was written in the code, since when the JavaScript runs, the HTML code has already been parsed into DOM objects.

However, your question seems to be more about whether a particular element type can contain text. This simple test will give you an answer per element type:

function canElementContainText(tagname) {
    try {
        var e = document.createElement(tagname);
        return e.outerHTML.indexOf("/") != -1;
    } catch (ex) {
        return false;
    }
}

For instance canElementContainText("div") returns true and canElementContainText("img") returns false.

You can then pass the tagName property of any element to this function to test it.

var result = canElementContainText(myElement.tagName);
wizulus
  • 5,653
  • 2
  • 23
  • 40
  • Instead of using innerText, try `appendChild(document.createTextNode(...)` – Zirak Feb 26 '14 at 16:39
  • 1
    Im trying that now, but firefox allows you to append anything to an `` – wizulus Feb 26 '14 at 16:40
  • Replaced with cross-browser compatible method tested in Firefox, Chrome, and IE11. Tested on http://jsfiddle.net/alancnet/tdBf3/ – wizulus Feb 26 '14 at 16:49
  • Nonetheless of all, updated script not working for every html tags, like `video`,`strong`... ! – nanobash Feb 26 '14 at 17:16
  • At this point, I would have to ask what problem you're trying to solve? Perhaps there is a better way to go about it? For instance, you could create an object that already has the answers: `{ div: true; img: false, video: false, span: true, ... }`... Or perhaps you can augment the faulty approach with such an object... – wizulus Feb 26 '14 at 17:18
  • I just mentioned that script doesn't work properly, in my opinion better way is to do like I've posted – nanobash Feb 26 '14 at 17:22
  • And the point of that kind of set could be very useful in dynamically generated `DOM` – nanobash Feb 26 '14 at 17:23
3

Following script works just fine (cross-browser issue resolved):

function containTxt(tag) {
    var tags = /^(img|video)$/i; // any values which will be in `tags` set will be treated as they can't have a text value
    return !tags.test(tag);
}

console.log(containTxt("img")); // returns false
console.log(containTxt("div")); // returns true
germanfr
  • 547
  • 5
  • 19
nanobash
  • 5,419
  • 7
  • 38
  • 56
  • This is good to check if a Tag actually *contains* text, but not if it *can* contain text. Thanks anyway! – Ood Feb 26 '14 at 15:52
0

use that:

canContainText: function(node) {
    if(node.nodeType === 3){
        return true;
    }
    if(node.nodeType === 1){
        return /<[^>]+><\/[^>]+>/gi.test(document.createElement(node.nodeName.toLowerCase())).outerHTML;
    }
}
dhomyakov
  • 1
  • 1
-4

Could use RegEx:

// these are samples, get elements text using element.innerHTML;
var one = "<a href='something'>Links</a>";
var two = "Lorem ipsum dolor";

function check(str){
    return str.match(/<[a-zA-Z]+.*>(.|\n)*<\/[a-zA-Z]+>/) ? true : false;
}

console.log(check(one)); // true
console.log(check(two)); // false
HighBoots
  • 293
  • 1
  • 5