简体   繁体   中英

How can I count the characters from a textarea?


I am trying to implement a character counter to my `textarea` tag, but something definitely isn't working. I tried several approaches, but unsuccessfully. I know there are lots of implementation on web, but I couldn't find something that is working to my code. I am quite beginner in this field, and I simply can't get how this works. Code:
 ............... <div id='id_text' class="control-group"> <label for="id_text" class="control-label"> Text </label> <div class="controls"> <label for="field"></label> <textarea id="field" onkeydown="countChar(this)" maxlength="800"></textarea> </div> <span>Char Left:</span> <span id="charNum"> </span> </div>....................................

script:

 <script src="http://code.jquery.com/jquery-1.5.js"></script> <script> function countChar(val) { var len = val.value.length; $('#charNum').text(800 - len); } </script>

NOTE: The script is positioned on the bottom of the HTML page (I tried to place it on top, but in vain). The script is simple: I just want to take the number of characters from the textarea and then to display the remaining characters to the user.

I looked for other answers here, I looked for answers on other websites, but I think there is a problem with my code and I don't get it.

NOTE2: The textarea is part of a <form> . And I am using django framework.

Thank you so much for your help and attention!

EDIT:

I have tried the code by Rory and this is what I see.

counting the characters from a textarea you have 2 ways in JavaScript

  1. to count characters with the spaces between words, you just have to get the content of your texarea, and mesure the "length". Remember: "The String prototype object has a "length" property whose initial value is 0 "

 //injecting "hello world" (10 characters and 1 space) into the DOM let newDiv = document.createElement("div") let newContent = document.createTextNode(`hello world`) newDiv.setAttribute("id", "Div1") newDiv.appendChild(newContent) document.body.appendChild(newDiv) let str = document.getElementById("Div1").innerHTML //counting the number of characters injected alert(`LENGHT = ` + `${str.length}`); // HERE THE PROPERTY LENGTH..

  1. here counting characters WITHOUT the spaces between words ":

 //injecting "hello world" (10 characters and 1 space) into the DOM let newDiv = document.createElement("div") let newContent = document.createTextNode(`hello world`) newDiv.setAttribute("id", "Div1") newDiv.appendChild(newContent) document.body.appendChild(newDiv) let str = document.getElementById("Div1").innerHTML //first you split the content using String.prototype.split ( separator, limit ) then concatenate the array obtained by the split without spaces using: Array.prototype.join ( separator ) alert(str.split(' ').join('').length)

UPDATE: About performance following the idea of @jallmer to use the method replace + REGEX

 //injecting "hello world" (10 characters and 1 space) into the DOM let newDiv = document.createElement("div") let newContent = document.createTextNode(`hello world`) newDiv.setAttribute("id", "Div1") newDiv.appendChild(newContent) document.body.appendChild(newDiv) //testing algorithms perfs let str1 = document.getElementById("Div1").innerHTML let str2= document.getElementById("Div1").innerHTML //testing algorithm 1 console.log(`str1 = ${str1}`) const t0 = performance.now(); console.log(str1.split(' ').join('').length) const t1 = performance.now() console.log(`algorithm 1 took ${t1 - t0} milliseconds.`); //testing method 2 console.log(`str2 = ${str2}`) const t2 = performance.now(); console.log(str2.replace(/\s/g, '').length) const t3 = performance.now() console.log(`algorithm 2 took ${t3 - t2} milliseconds.`);

and curiously the results are different on my chrome dev tools (Chrome for Gnu/Linux, version 90.0.4430.93 (Official Build) (64-bit)). Something to inspect比较了这两种算法,呈现了两种截然不同的表现:String.split().join().length vs String.replace().length。结果取决于您使用的解释器(代码片段与 chrome 开发工具) :

The keydown event fires before the value in the field has been updated. As such your JS is displaying the character calculation from the previous keypress. keyup is the better choice of the two.

However, that being said, you should use the input event instead as it covers all cases where the value of the field changes which keydown / keyup don't - for example copy & paste using the mouse.

Also note that jQuery 1.5 is massively outdated - over 10 years old in fact. You should be using the latest version which at time of answering is 3.6. In addition using onX event attributes is no longer good practice. Look to attach your event handlers unobtrusively without including any JS in the HTML. As you're using jQuery already you can use the on() method to do that

With all that said, try this:

 jQuery($ => { const $charNum = $('#charNum'); $('#field').on('input', e => { let len = e.target.value.length; $charNum.text(800 - len); }).trigger('input'); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <div id='id_text' class="control-group"> <label for="id_text" class="control-label">Text</label> <div class="controls"> <label for="field"></label> <textarea id="field" maxlength="800"></textarea> </div> <span>Char Left:</span> <span id="charNum"> </span> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM