Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get text of an element without children in javascript

How do I get the text of an element without the children? Neither element.textContent nor element.innerText seem to be working.

HTML:

<body>
<h1>Test Heading</h1>
<div>
Awesome video and music. Thumbs way up. Love it. Happy weekend to you and your family. Love, Sasha
</div>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
    fool("body");
</script>

and here's the fool function:

jQuery.fn.justtext = function(text) {
    return $(this).clone()
    .children()
    .remove()
    .end()
    .text();
};

function fool(el) { 

    reverse(el);

    function reverse(el) {
        $(el).children().each(function() {
            if($(this).children().length > 0) {
                reverse(this);
                if($(this).justtext() != "")
                    reverseText(this);
            } else {
               reverseText(this)
            }
        });
    }

    function reverseText(el){
        var text = el.textContent;
        var frag = text.toString().split(/ /);
        var foo = "";
        var punctation_marks = [".",",","?","!"," ",":",";"];
        for(i in frag){
            if(punctation_marks.indexOf(frag[i]) == -1)
                foo += actualReverse(frag[i],punctation_marks) + " ";
        }
        el.textContent = foo;
    }

    function actualReverse(text,punctation_marks) {
        return (punctation_marks.indexOf(text.split("")[text.split("").length-1]) != -1)?text.split("").slice(0,text.split("").length-1).reverse().join("") + text.split("")[text.split("").length-1] : text.split("").reverse().join("");
    }
}

edit: using node.nodeType doesn't really help and here's why: Imaginge the following HTML

<td class="gensmall">
    Last visit was: Sat Mar 31, 2012 10:50 am
    <br>
    <a href="./search.php?search_id=unanswered">View unanswered posts</a> | <a href="./search.php?search_id=active_topics">View active topics</a>
</td>

if I'd use nodeType, only the text of the a element would change , but not the td itself ("last visit....")

like image 626
Nik Avatar asked Mar 31 '12 12:03

Nik


People also ask

How do I get text in Javascript?

Use the textContent property to get the text of an html element, e.g. const text = box. textContent . The textContent property returns the text content of the element and its descendants. If the element is empty, an empty string is returned.

What does textContent mean in Javascript?

Definition and Usage The textContent property sets or returns the text content of the specified node, and all its descendants.

Should I use innerHTML or textContent?

innerHTML returns HTML, as its name indicates. Sometimes people use innerHTML to retrieve or write text inside an element, but textContent has better performance because its value is not parsed as HTML. Moreover, using textContent can prevent XSS attacks.

How do you check if an element has a child in JS?

To check if an HTML element has child nodes, you can use the hasChildNodes() method. This method returns true if the specified node has any child nodes, otherwise false . Whitespace and comments inside a node are also considered as text and comment nodes.


2 Answers

Just find the text nodes:

var element = document.getElementById('whatever'), text = '';
for (var i = 0; i < element.childNodes.length; ++i)
  if (element.childNodes[i].nodeType === Node.TEXT_NODE)
    text += element.childNodes[i].textContent;

edit — if you want the text in descendant ("children") nodes, and (as is now apparent) you're using jQuery:

$.fn.allText = function() {
  var text = '';
  this.each(function() {
    $(this).contents().each(function() {
      if (this.nodeType == Node.TEXT_NODE)
        text += this.textContent;
      else if (this.nodeType == Node.ELEMENT_NODE)
        text += $(this).allText();
    });
  });
  return text;
};

Hold on and I'll test that out :-) (seems to work)

like image 108
Pointy Avatar answered Sep 27 '22 20:09

Pointy


This code achieves the same result as the two other answers, but in a more expressive, functional way. The filter and map array methods are supported in all modern browsers (IE9 and up).

Throwing this in there since the other answers are a bit dated by now.

var content = Array.prototype.filter.call(element.childNodes, function (element) {
    return element.nodeType === Node.TEXT_NODE;
}).map(function (element) {
    return element.textContent;
}).join("");
like image 34
fredrikekelund Avatar answered Sep 27 '22 19:09

fredrikekelund