2009-04-19 7 views
15

Me pregunto si hay una forma de contar las palabras dentro de un div por ejemplo. Digamos que tenemos un div de este modo:Cuenta de palabras de Javascript para cualquier elemento DOM dado

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

continuación, tiene la función de JS devolver un número entero de 4.

Es esto posible? He hecho esto con elementos de formulario, pero parece que no puedo hacerlo para los que no tienen forma.

¿Alguna idea?

g

Respuesta

31

Si sabe que el DIV es solamente va a tener el texto en ella, puede KISS:

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

Si el div puede tener etiquetas HTML en ella, eres va a tener que atravesar sus hijos en busca de los nodos de texto:

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; 

Esta es la misma lógica que utiliza la librería jQuery para lograr º El efecto de su función text(). jQuery es una biblioteca bastante impresionante que en este caso no es necesaria. Sin embargo, si te encuentras realizando una gran cantidad de manipulación de DOM o AJAX, es posible que quieras comprobarlo.

EDITAR:

Como señaló Gumbo en los comentarios, la forma en que se están dividiendo por encima de las cuerdas contaría dos espacios consecutivos como una palabra. Si espera ese tipo de cosas (e incluso si no lo hace), probablemente sea mejor evitarlo dividiendo en una expresión regular en lugar de en un carácter de espacio simple. Teniendo esto en mente, en lugar de hacer la división anterior, usted debe hacer algo como esto:

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

La única diferencia es en lo que estamos pasando a la función split.

+0

Vas a tener que conseguir el primer nodo de texto. – cgp

+0

¡perfecto! gracias – givp

+0

Esto contará las etiquetas como palabras, por lo que preferiría la versión de texto() proporcionada por jQuery. – cgp

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

Estaría bastante estrictos acerca de lo que una palabra es- segunda solución de

function countwords(hoo){ 
    var text= document.deepText(hoo).join(' '); 
    return text.match(/[A-Za-z\'\-]+/g).length; 
} 
alert(countwords(document.body)) 
6

Paolo Bergantino es incorrecta para las cadenas vacías o cadenas que comienzan o terminan con espacios en blanco. Aquí está la solución:

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

Explicación: Si la cadena está vacía, hay cero palabras; Si la cadena tiene solo espacios en blanco, hay cero palabras; De lo contrario, cuente la cantidad de grupos de espacios en blanco sin los del principio y el final de la cadena.

1

O usted puede hacer esto:

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; 
} 
5
string_var.match(/[^\s]+/g).length 

parece que es un método mejor que

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

Al menos no contará "palabra" como 2 palabras - [ 'palabra'] en lugar de ['palabra', ''].Y realmente no requiere ninguna lógica de complemento divertida.

+0

Mejor, pero todavía cuenta cadena vacía '' como 1. Pruebe: 'string_var.match (/ [^ \ s] +/g) .length - 1;' –

0

La función get_text en la respuesta de Paolo Bergantino no funcionó correctamente para mí cuando dos nodos secundarios no tienen espacio entre ellos. por ejemplo <h1> partida </h1 > <p> párrafo </p > serían devueltos como headingparagraph (aviso falta de espacio entre las palabras). Así que anteponer un espacio a nodeValue corrige esto. Pero introduce un espacio en la parte frontal del texto, pero encontré una función de recuento de palabras que lo recorta (además, usa varias expresiones regulares para garantizar que solo cuente las palabras). Número de palabras y funciones get_text editado a continuación:

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

Editar palabra

de Kennebec contador es realmente bueno. Pero el que he encontrado incluye un número como palabra, que es lo que necesitaba. Aún así, eso es fácil de agregar a Kennebec. Pero la función de recuperación de texto de Kennebec tendrá el mismo problema.

0

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

Cuestiones relacionadas