任何给定DOM元素的JavaScript字数统计

20
我想知道是否有一种方法可以计算一个 div 内的单词数。比如说我们有这样一个 div:
<div id="content">
hello how are you?
</div>

那么让这个JS函数返回一个整数4。

这可行吗?我已经对表单元素使用过了,但好像不能用在非表单元素上。

有什么想法吗?

g

9个回答

36

如果您知道该 DIV 中 仅包含文本,您可以采用KISS原则:

var count = document.getElementById('content').innerHTML.split(' ').length;
如果div中可以有HTML标签,那么你需要遍历它的子元素来查找文本节点:
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;

这是与jQuery库使用相同逻辑的代码,用于实现其text()函数的效果。在这种情况下,jQuery是一个非常棒的库,但并不是必需的。然而,如果您发现自己需要频繁进行DOM操作或AJAX,则可能需要考虑使用它。

编辑

如评论中Gumbo所指出的那样,以上我们将连续两个空格视为一个单词。如果您希望考虑到这种情况(即使您不希望),最好避免使用简单的空格字符分割字符串,而应该使用正则表达式进行拆分。记住这一点,您应该像这样进行操作:

var count = words.split(/\s+/).length;
唯一的区别就在于我们向 split 函数传递的参数不同。

您需要先获取文本节点。 - cgp
这将把标签算作单词,因此我更喜欢 jQuery 提供的 text() 版本。 - cgp
2
我知道,我一发布它就开始转换文本到纯JavaScript,以提供另一种选择。并不是每个人都需要jQuery。 :) - Paolo Bergantino
1
最好使用正则表达式来考虑多个空格字符。 - Gumbo
.textContent(或者在IE中使用.innerText)难道不足以替代下降遍历吗? - Crescent Fresh
显示剩余4条评论

7

Paolo Bergantino的第二个解决方案对于空字符串或以空格开头或结尾的字符串是不正确的。这里是修复方法:

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

说明:如果字符串为空,则没有单词; 如果字符串只有空格,则没有单词;否则,计算不包括字符串开头和结尾的空格组数。


6
string_var.match(/[^\s]+/g).length

似乎这是一种比之前更好的方法。
string_var.split(/\s+/).length

至少它不会将“word”视为2个单词——而是 ['word'] 而不是 ['word', '']。并且它实际上并不需要任何有趣的附加逻辑。

更好了,但仍然将空字符串''算作1。尝试:string_var.match(/[^\s]+/g).length - 1; - Geoffrey Hale

5

3
document.deepText= function(hoo){
    var A= [];
    if(hoo){
        hoo= hoo.firstChild;
        while(hoo!= null){
            if(hoo.nodeType== 3){
                A[A.length]= hoo.data;
            }
            else A= A.concat(arguments.callee(hoo));
            hoo= hoo.nextSibling;
        }
    }
    return A;
}

我会对“单词”的定义非常严格-


注:本段内容涉及语言学术语,可能需要进一步解释。
function countwords(hoo){
    var text= document.deepText(hoo).join(' ');
    return text.match(/[A-Za-z\'\-]+/g).length;
}
alert(countwords(document.body))

1

或者你可以这样做:

function CountWords (this_field, show_word_count, show_char_count) {
    if (show_word_count == null) {
        show_word_count = true;
    }
    if (show_char_count == null) {
        show_char_count = false;
    }
    var char_count = this_field.value.length;
    var fullStr = this_field.value + " ";
    var initial_whitespace_rExp = /^[^A-Za-z0-9]+/gi;
    var left_trimmedStr = fullStr.replace(initial_whitespace_rExp, "");
    var non_alphanumerics_rExp = rExp = /[^A-Za-z0-9]+/gi;
    var cleanedStr = left_trimmedStr.replace(non_alphanumerics_rExp, " ");
    var splitString = cleanedStr.split(" ");
    var word_count = splitString.length -1;
    if (fullStr.length <2) {
        word_count = 0;
    }
    if (word_count == 1) {
        wordOrWords = " word";
    } else {
        wordOrWords = " words";
    }
    if (char_count == 1) {
        charOrChars = " character";
    } else {
        charOrChars = " characters";
    }
    if (show_word_count & show_char_count) {
        alert ("Word Count:\n" + "    " + word_count + wordOrWords + "\n" + "    " + char_count + charOrChars);
    } else {
        if (show_word_count) {
            alert ("Word Count:  " + word_count + wordOrWords);
        } else {
            if (show_char_count) {
                alert ("Character Count:  " + char_count + charOrChars);
            }
        }
    }
    return word_count;
}

1

这应该考虑到前面和后面的空白字符

const wordCount = document.querySelector('#content').innerText.trim().split(/\s+/).length;

+1 for innerTextinnerText属性提供了从HTML元素中获取文本的内置功能,而其他答案提供了解决同一问题的自定义解决方案。 - FThompson

1

Paolo Bergantino答案中的get_text函数在我的情况下无法正确工作,当两个子节点之间没有空格时。例如<h1>标题</h1><p>段落</p>将返回为headingparagraph(注意单词之间缺少空格)。因此,在nodeValue之前添加一个空格可以解决这个问题。但是它会在文本前面引入一个空格,但我找到了一个可以修剪它的字数计数函数(还使用了几个正则表达式以确保只计算单词)。以下是字数计数和编辑后的get_text函数:

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;
}

function wordCount(fullStr) {
    if (fullStr.length == 0) {
        return 0;
    } else {
        fullStr = fullStr.replace(/\r+/g, " ");
        fullStr = fullStr.replace(/\n+/g, " ");
        fullStr = fullStr.replace(/[^A-Za-z0-9 ]+/gi, "");
        fullStr = fullStr.replace(/^\s+/, "");
        fullStr = fullStr.replace(/\s+$/, "");
        fullStr = fullStr.replace(/\s+/gi, " ");
        var splitString = fullStr.split(" ");
        return splitString.length;
    }
}

编辑

kennebec的字数统计工具非常好用。但我找到的那个包括数字在内,这正是我所需要的。不过,这很容易添加到kennebec的工具中。但是,kennebec的文本检索功能也会遇到同样的问题。


0

string_var.match(/[^\s]+/g).length - 1;

这段代码是关于编程的,它的作用是计算字符串中空格以外的单词数量。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接