简体   繁体   English

如何计算文本区域中的字符?

[英]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. 我正在尝试为我的 `textarea` 标签实现一个字符计数器,但某些东西肯定是行不通的。 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. 我知道 web 上有很多实现,但我找不到适用于我的代码的东西。 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).注意:该脚本位于 HTML 页面的底部(我试图将其放在顶部,但徒劳无功)。 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.脚本很简单:我只想从 textarea 中获取字符数,然后将剩余的字符显示给用户。

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> .注意 2: textarea 是<form>的一部分。 And I am using django framework.我正在使用 django 框架。

Thank you so much for your help and attention!非常感谢您的帮助和关注!

EDIT:编辑:

I have tried the code by Rory and this is what I see.我已经尝试了 Rory 的代码,这就是我所看到的。

counting the characters from a textarea you have 2 ways in JavaScript计算文本区域中的字符,您在 JavaScript 中有两种方法

  1. to count characters with the spaces between words, you just have to get the content of your texarea, and mesure the "length".要计算单词之间的空格字符,您只需要获取 texarea 的内容,并测量“长度”。 Remember: "The String prototype object has a "length" property whose initial value is 0 "请记住: “字符串原型 object 有一个初始值为 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更新:关于性能遵循@jallmer 的想法使用方法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)).奇怪的是,我的 chrome 开发工具(Chrome for Gnu/Linux,版本 90.0.4430.93(官方构建)(64 位))的结果不同。 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. keydown事件在字段中的值更新之前触发。 As such your JS is displaying the character calculation from the previous keypress.因此,您的 JS 正在显示上一次按键的字符计算。 keyup is the better choice of the two. keyup是两者中更好的选择。

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.但是,话虽如此,您应该改用input事件,因为它涵盖了字段值更改而keydown / keyup不会更改的所有情况 - 例如使用鼠标复制和粘贴。

Also note that jQuery 1.5 is massively outdated - over 10 years old in fact.另请注意,jQuery 1.5 已严重过时 - 实际上已有 10 多年的历史。 You should be using the latest version which at time of answering is 3.6.您应该使用在回答时为 3.6 的最新版本。 In addition using onX event attributes is no longer good practice.此外,使用onX事件属性不再是好的做法。 Look to attach your event handlers unobtrusively without including any JS in the HTML.在 HTML 中不包含任何 JS 的情况下,以不显眼的方式附加您的事件处理程序。 As you're using jQuery already you can use the on() method to do that当您已经使用 jQuery 时,您可以使用on()方法来做到这一点

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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