Estoy usando el siguiente código para calcular palabras, caracteres y líneas.
function wordCount( val ){ var wom = val.match(/\S+/g); return { charactersNoSpaces : val.replace(/\s+/g, '').length, characters : val.length, words : wom ? wom.length : 0, lines : val.split(/\r*\n/).length }; } var textarea = document.getElementById("text"); var result = document.getElementById("result"); textarea.addEventListener("input", function(){ var v = wordCount( this.value ); result.innerHTML = ( "<br>Characters (no spaces): "+ v.charactersNoSpaces + "<br>Characters (and spaces): "+ v.characters + "<br>Words: "+ v.words + "<br>Lines: "+ v.lines ); }, false); <textarea id="text"></textarea> <div id="result"></div>inicialmente todo se pone a cero. Cuando escribimos cuenta bien. Pero cuando borramos el cuadro de texto, Lines muestra el valor como 1 aunque no hay textos en el cuadro de texto. ¿Cómo hacer que la línea cuente cero?
Me di cuenta de que dividir val hace que la longitud sea 1 incluso si está vacío:
// val is empty and it length is null // But after splitting it would be one val.split(/\r*\n/).length // 1 function wordCount( val ){ var wom = val.match(/\S+/g); return { charactersNoSpaces : val.replace(/\s+/g, '').length, characters : val.length, words : wom ? wom.length : 0, lines : val.length ? val.split(/\r*\n/).length : val.length }; } var textarea = document.getElementById("text"); var result = document.getElementById("result"); textarea.addEventListener("input", function(){ var v = wordCount( this.value ); result.innerHTML = ( "<br>Characters (no spaces): "+ v.charactersNoSpaces + "<br>Characters (and spaces): "+ v.characters + "<br>Words: "+ v.words + "<br>Lines: "+ v.lines ); }, false); <textarea id="text"></textarea> <div id="result"></div>Cuando se divide una cadena, si ninguno de los delimitadores coincide, se quedará con la cadena original.
const foo = 'foo'; console.log(foo.split(/bar/).length); Lo mismo ocurre con la cadena vacía: cuando se divide, aún le dará [''] , que tiene una longitud ...
Puede hacer coincidir las líneas que tienen al menos un carácter en ellas en lugar de dividirlas, excluyendo así las líneas vacías.
lines: (val.match(/^./gm) || []).lengthSi divide una cadena vacía, el resultado es [""] , una matriz con un elemento que es una cadena vacía.
Puede verificar este caso primero con una expresión condicional.
Además, no es necesario usar \r* en el delimitador de división, ya que no influye en el conteo.
function wordCount( val ){ var wom = val.match(/\S+/g); return { charactersNoSpaces : val.replace(/\s+/g, '').length, characters : val.length, words : wom ? wom.length : 0, lines : val.length == 0 ? 0 : val.split('\n').length }; } var textarea = document.getElementById("text"); var result = document.getElementById("result"); textarea.addEventListener("input", function(){ var v = wordCount( this.value ); result.innerHTML = ( "<br>Characters (no spaces): "+ v.charactersNoSpaces + "<br>Characters (and spaces): "+ v.characters + "<br>Words: "+ v.words + "<br>Lines: "+ v.lines ); }, false); <textarea id="text"></textarea> <div id="result"></div>