Videos
As for the question which event you should use for this: use the input event, and fall back to keyup/keydown in older browsers.
Here’s an example, DOM0-style:
someElement.oninput = function() {
this.onkeydown = null;
// Your code goes here
};
someElement.onkeydown = function() {
// Your code goes here
};
The other question is how to count the number of characters in the string. Depending on your definition of “character”, all answers posted so far are incorrect. The string.length answer is only reliable when you’re certain that only BMP Unicode symbols will be entered. For example, 'a'.length == 1, as you’d expect.
However, for supplementary (non-BMP) symbols, things are a bit different. For example, '𝌆'.length == 2, even though there’s only one Unicode symbol there. This is because JavaScript exposes UCS-2 code units as “characters”.
Luckily, it’s still possible to count the number of Unicode symbols in a JavaScript string through some hackery. You could use Punycode.js’s utility functions to convert between UCS-2 strings and Unicode code points for this:
// `String.length` replacement that only counts full Unicode characters
punycode.ucs2.decode('a').length; // 1
punycode.ucs2.decode('𝌆').length; // 1 (note that `'𝌆'.length == 2`!)
P.S. I just noticed the counter script that Stack Overflow uses gets this wrong. Try entering 𝌆, and you’ll see that it (incorrectly) counts as two characters.
UPDATE: Since I wrote this, the input event has gotten a decent level of support. It is still not 100% in IE9, so you will have to wait a bit until IE9 is fully phased out. In light of my answer to this question, however, input is more than a decent replacement for the method I've presented, so I recommend switching.
Use keyup event
var inp = document.getElementById('myinput');
var chars = document.getElementById('chars');
inp.onkeyup = function() {
chars.innerHTML = inp.value.length;
}
<input id="myinput"><span id="chars">0</span>
EDIT:
Just a note for those that suggest keydown. That won't work. The keydown fires before character is added to the input box or textarea, so the length of the value would be wrong (one step behind). Therefore, the only solution that works is keyup, which fires after the character is added.
(V8 developer here.)
I can see several issues here that can be looked at separately:
1. From a language specification perspective, is something a method or a property?
Intuitively, the distinction is: if you write a function call like obj.method(), then it's a method; if you write obj.property (no ()), then it's a property.
Of course in JavaScript, you could also say that everything is a property, and in case the current value of the property is a function, then that makes it a method. So obj.method gets you a reference to that function, and obj.method() gets and immediately calls it:
Copyvar obj = {};
obj.foo = function() { console.log("function called"); return 42; }
var x = obj.foo(); // A method!
var func = obj.foo; // A property!
x = func(); // A call!
obj.foo = 42;
obj.foo(); // A TypeError!
2. When it looks like a property access, is it always a direct read/write from/to memory, or might some function get executed under the hood?
The latter. JavaScript itself even provides this capability to objects you can create:
Copyvar obj = {};
Object.defineProperty(obj, "property", {
get: function() { console.log("getter was called"); return 42; },
set: function(x) { console.log("setter was called"); }
});
// *Looks* like a pair of property accesses, but will call getter and setter:
obj.property = obj.property + 1;
The key is that users of this obj don't have to care that getters/setters are involved, to them .property looks like a property. This is of course very much intentional: implementation details of obj are abstracted away; you could modify the part of the code that sets up obj and its .property from a plain property to a getter/setter pair or vice versa without having to worry about updating other parts of the code that read/write it.
Some built-in objects rely on this trick, the most common example is arrays' .length: while it's specified to be a property with certain "magic" behavior, the most straightforward way for engines to implement this is to use a getter/setter pair under the hood, where in particular the setter does the work of truncating any extra array elements if you set the length to a smaller value than before.
3. So what does "abc".length do in V8?
It reads a property directly from memory. All strings in V8 always have a length field internally. As commenters have pointed out, JavaScript strings are immutable, so the internal length field is written only once (when the string is created), and then becomes a read-only property.
Of course this is an internal implementation detail. Hypothetically, an engine could use a "C-style" string format internally, and then it would have to use a strlen()-like function to determine a string's length when needed. However, on a managed heap, being able to quickly determine each object's size is generally important for performance, so I'd be surprised if an engine actually made this choice. "Pascal-style" strings, where the length is stored explicitly, are more suitable for JavaScript and similar garbage-collected languages.
So, in particular, I'd say it's fair to assume that reading myString.length in JavaScript is always a very fast operation regardless of the string's length, because it does not iterate the string.
4. What about String.length?
Well, this doesn't have anything to do with strings or their lengths :-)
String is a function (e.g. you can call String(123) to get "123"), and all functions have a length property describing their number of formal parameters:
Copyfunction two_params(a, b) { }
console.log(two_params.length); // 2
As for whether that's a "simple property" or a getter under the hood: there's no reason to assume that it's not a simple property, but there's also no reason to assume that engines can't internally do whatever they want (so long as there's no observable functional difference) if they think it increases performance or saves memory or simplifies things or improves some other metric they care about :-)
(And engines can and do make use of this freedom, for various forms of "lazy"/on-demand computation, caching, optimization -- there are plenty of internal function calls that you probably wouldn't expect, and on the flip side what you "clearly see" as a function call in the JS source might (or might not!) get inlined or otherwise optimized away. The details change over time, and across different engines.)
Length is not a method, it is a property. It doesn't actually do anything but return the length of an array, a string, or the number of parameters expected by a function. When you use .length, you are just asking the JavaScript interpreter to return a variable stored within an object; you are not calling a method.
Also, note that the String.length property gives the actual number of code units in a string, rather than a literal character count. One code unit is 16 bits as defined by UTF-16 (used by JavaScript). However, some special characters use 32 bits which means that in a string containing one of these characters the String.length property might give you a higher character count than the literal number of characters.
Link:- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length
And also one fact length work very different with string.length from Array.length
Copylet myString = "bluebells";
myString.length = 4;
console.log(myString); //bluebells
console.log(myString.length); //9
//--
let myArr = [5,6,8,2,4,7];
myArr.length = 2;
console.log(myArr); //[5, 6]
console.log(myArr.length); //2