Количество слов в Javascript для любого элемента DOM - PullRequest
16 голосов
/ 19 апреля 2009

Мне интересно, есть ли способ подсчитать слова внутри div, например. Скажем, у нас есть div как:

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

Затем функция JS возвращает целое число 4.

Возможно ли это? Я сделал это с элементами формы, но не могу сделать это для неформальных элементов.

Есть идеи?

г

Ответы [ 8 ]

31 голосов
/ 19 апреля 2009

Если вы знаете, что 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, вы можете проверить это.

EDIT

Как отметил Гамбо в комментариях, то, как мы разбиваем строки выше, будет означать два последовательных пробела как слово. Если вы ожидаете такого рода вещи (и даже если вы этого не делаете), то, вероятно, лучше избегать этого, разделяя регулярное выражение вместо простого пробела. Имея это в виду, вместо того, чтобы делать вышеупомянутое разделение, вы должны сделать что-то вроде этого:

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

Единственное отличие состоит в том, что мы передаем функции split .

7 голосов
/ 19 мая 2011

Второе решение Паоло Бергантино неверно для пустых строк или строк, начинающихся или заканчивающихся пробелами. Вот исправление:

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

Объяснение: Если строка пуста, есть нулевые слова; Если в строке есть только пробелы, есть ноль слов; В противном случае подсчитайте количество групп без пробелов без групп в начале и конце строки.

5 голосов
/ 17 июля 2012
string_var.match(/[^\s]+/g).length

кажется, что это лучший метод, чем

string_var.split(/\s+/).length

По крайней мере, слово не будет считаться как 2 слова - ['слово'], а не ['слово', '']. И это действительно не требует никакой забавной логики дополнения.

4 голосов
/ 22 июля 2013

Или просто используйте Countable.js , чтобы выполнить тяжелую работу;)

2 голосов
/ 20 апреля 2009
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 голос
/ 20 июня 2011

Или вы можете сделать это:

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;
}
0 голосов
/ 30 июля 2015

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

0 голосов
/ 19 октября 2012

Функция get_text в ответе Паоло Бергантино не сработала для меня, когда между двумя дочерними узлами нет пробелов. например,

заголовок

абзац

будет возвращен в качестве заголовка (обратите внимание на отсутствие пробела между словами). Таким образом, добавление пробела к 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;
    }
}

EDIT

Счетчик слов Кеннебека действительно хорош. Но тот, который я нашел, включает в себя число в виде слова, которое мне и нужно. Тем не менее, это легко добавить к Кеннебеку. Но у функции поиска текста в kennebec будет та же проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...