Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript word-count for any given DOM element

Tags:

javascript

I'm wondering if there's a way to count the words inside a div for example. Say we have a div like so:

<div id="content">
hello how are you?
</div>

Then have the JS function return an integer of 4.

Is this possible? I have done this with form elements but can't seem to do it for non-form ones.

Any ideas?

g

like image 218
givp Avatar asked Apr 19 '09 13:04

givp


2 Answers

If you know that the DIV is only going to have text in it, you can KISS:

var count = document.getElementById('content').innerHTML.split(' ').length;

If the div can have HTML tags in it, you're going to have to traverse its children looking for text nodes:

function get_text(el) {
    ret = "";
    var length = el.childNodes.length;
    for(var i = 0; i < length; i++) {
        var node = el.childNodes[i];
        if(node.nodeType != 8) {
            ret += node.nodeType != 1 ? node.nodeValue : get_text(node);
        }
    }
    return ret;
}
var words = get_text(document.getElementById('content'));
var count = words.split(' ').length;

This is the same logic that the jQuery library uses to achieve the effect of its text() function. jQuery is a pretty awesome library that in this case is not necessary. However, if you find yourself doing a lot of DOM manipulation or AJAX then you might want to check it out.

EDIT:

As noted by Gumbo in the comments, the way we are splitting the strings above would count two consecutive spaces as a word. If you expect that sort of thing (and even if you don't) it's probably best to avoid it by splitting on a regular expression instead of on a simple space character. Keeping that in mind, instead of doing the above split, you should do something like this:

var count = words.split(/\s+/).length;

The only difference being on what we're passing to the split function.

like image 92
Paolo Bergantino Avatar answered Oct 22 '22 04:10

Paolo Bergantino


Paolo Bergantino's second solution is incorrect for empty strings or strings that begin or end with whitespaces. Here's the fix:

var count = !s ? 0 : (s.split(/^\s+$/).length === 2 ? 0 : 2 +
    s.split(/\s+/).length - s.split(/^\s+/).length - s.split(/\s+$/).length);

Explanation: If the string is empty, there are zero words; If the string has only whitespaces, there are zero words; Else, count the number of whitespace groups without the ones from the beginning and the end of the string.

like image 33
liviucmg Avatar answered Oct 22 '22 05:10

liviucmg