所以我想告诉用户他们有多少个字符是动态输入的。我在网上看到了几个使用“Onchange”或“OnKeyUp”的例子,但它们都是老例子,而且看起来很蹩脚。优雅的方式来计算textarea /输入框中的字符数
有没有更好的方法?也许某种绑定/分配的方法(可能不会正确使用这个术语)将值赋给一个变量,然后每次检查一次变化就进行检查?
所以我想告诉用户他们有多少个字符是动态输入的。我在网上看到了几个使用“Onchange”或“OnKeyUp”的例子,但它们都是老例子,而且看起来很蹩脚。优雅的方式来计算textarea /输入框中的字符数
有没有更好的方法?也许某种绑定/分配的方法(可能不会正确使用这个术语)将值赋给一个变量,然后每次检查一次变化就进行检查?
当你在谈论动态显示输入了多少个字符时,你需要事件,如onchange
或onkeyup
......真的没有别的办法。
更重要的是:“将值分配给变量并检查每次更改是否已完成”除了通过onchange
还可以知道您需要检查以及何时检查什么?
这样做的快速,简便的方法:
document.getElementById('aninputId').onchange= function(e)
{
console.log(this.value.length);//or alert(); do with this value what you want
};
要记住一个重要的事情是,如果你处理了很多元素,你可能要考虑委派事件。 here你可以找到一个类似(不重复)的问题与2个答案,处理事件委托。谷歌它了解更多关于这个强大的功能!
UPDATE(与小提琴)
好的,我建立this quick fiddle如使用事件代理的例子。我使用了onchange
,所以在焦点丢失之前长度不会显示出来,有些评论会告诉你代码的作用,但是它的写法相当匆忙。如果您对此示例有任何疑问,请告诉我。
PS:如果你想在实时改变,长度只需更换
mainDiv.addEventListener('onchange',showLength,false);
与
mainDiv.addEventListener('keyup',showLength,false);
仅此而已吧!
UPDATE2
在回答你的最后的评论:没有,该代码将无法正常工作。 alert(e);
行会尝试提醒event object
,所以只能在IE上看到'[object object]',如果不是undefined
。
为了帮助您了解从我的jsfiddle代码的功能,我会一步分解,并通过它,一步:
在我的例子中,输入字段(这里只有1,但有可能有一直是100的)都是一个主要的div元素#allInputs
的孩子。所以首先,我们得到这个元素的引用:
var mainDiv = document.getElementById('allInputs');//Here's where we'll listen for events
然后,我们想要一个事件侦听器附加到该div。由于IE中的事件冒泡,以及所有其他浏览器中的事件捕获,在此元素内触发的所有事件都将通过div传递。 Here是一些图表,可能会澄清我的意思。这是事件代表团的关键概念。一旦你得到这个,其余的很容易。
现在,回到聆听事件:addEventListener
做它在锡上说的:它附加到一个元素,并侦听在该元素内被触发/分派的事件。如果这些事件中的任何一个是指定的类型,它将调用一个函数。这个函数被称为回调函数,或者在这种情况下是事件处理函数。一如往常IE不像所有其他浏览器一样工作,所以首先我们检查是否可以使用addEventHandler
方法。
if (!(mainDiv.addEventListener))
{//if not: this is the IE way
mainDiv.attachEvent('onfocusout',showLength);
}
else
{
mainDiv.addEventListener('change',showLength,false);
}
在这两种情况下,第一个参数是一个字符串,指出我们要听的事件类型,在大多数情况下addEventListener
从事件类型的名称滴on
。 IE再次固执并不支持onchange
事件被委派(它不会冒泡),我们通过监听另一个事件来解决这个问题:IE自己的onfocusout事件(如果输入元素失去焦点,它很有可能被用于输入,并具有新的价值。这使得它在正确的时刻来检查值长度。addEventListener
有第三个参数,以捕捉的情况下,这是在这种情况下无关紧要,但在怪异模式(该链接以上),可以为实际回调阅读更多关于这个话题,我建议你这样做。
function showLength(e)
{
e = e || window.event;
var target = e.target || e.srcElement;//ie== srcElement, good browsers: target
if (target.tagName.toLowerCase() === 'input' && target.type === 'text')
{
document.getElementById(target.id + 'Span').innerHTML = target.value.length;
}
}
现在,声明这个功能,就像使用其他任何功能,并指定1种说法,在这种情况下e
或event
- 无所谓你称之为。 (可能有多个参数,但是我们必须进入关闭状态,我会尽力并坚持这里的基础知识)。
事件对象在被大多数浏览器调用时将传递给处理函数,猜测哪个浏览器不会传递此对象?是的,我们的老朋友IE浏览器,但是这是一个简单的办法:功能e = e || window.event;
的第一行可以写成:
if (e === undefined)
{
e = window.event;
}
为什么?因为我们亲爱的朋友Internet Explorer不会将事件对象传递给处理程序,而是将其保留在全局对象中,我们可以通过window.event
访问该对象。
我们需要的下一件事是找出触发事件的元素。假设你有一个表单,其中有20个输入字段,10个单选按钮和16个选择元素,我们检测到事件的级别为div#allInputs
,我们只知道该事件在此元素中设置。幸运的是,事件对象具有保持于我们所需要的元素的引用的属性:
var target = e.target || e.srcElement;
同样,IE是不同的。如果您已经阅读(并记住)quirksmode页面上的内容:IE事件首先在元素级触发,然后在DOM中向上冒泡,而所有W3C浏览器都在顶级调度事件,并将其传递给它直至实际的元素。这解释了实际上属于同一属性的不同名称:W3C事件被分派,然后查找它们的元素,IE事件在元素上分派,并从其源代码冒泡。 - 我正在漂流。
在这个阶段我们知道些什么?我们需要知道的一切,真的。我们知道发生了什么事件(e.type
会告诉我们 - 在这种情况下,无论是改变还是专注)。我们什么元素已经改变/失去了焦点,并且在变量target
中引用了该元素,因此我们可以得到它的值(target.value
),它是id(target.id
)和and,更重要的是:我们可以检查我们是否想要进一步做任何事情:
if (target.tagName.toLowerCase() === 'input' && target.type === 'text')
记得我谈过,你正在处理30+元素,并不是所有的文本输入框的形式的情况呢?如果在select元素中选择了新选项,我们不想显示select的value属性的长度,对吗?因此我们检查target
是否为input
标签。
这仍然可以是任何输入元素想象,让我们也检查它的类型,只要target
是一个文本输入将我们显示长度:
document.getElementById(target.id + 'Span').innerHTML = target.value.length;
//or, if you want:
alert(target.value.length);
什么是比直接绑定的这个优点事件?再次强调:如果您将更改事件分别绑定到多个元素,您的用户将会通知。作为一个额外的好处:选择,文本输入,广播,......全部的变化事件可以由1个功能处理。它只需要一个switch语句。相反的:
if (target.tagName.toLowerCase() === 'input' && target.type === 'text')
{
document.getElementById(target.id + 'Span').innerHTML = target.value.length;
}
试试这个:
if (target.tagName.toLowerCase() === 'select')
{
alert('You\'ve selected option number: ' + (target.selectedIndex + 1));
}
if (target.tagName.toLowerCase() !== 'input')
{//suppose I only want to deal with input and select elements
return;
}
switch(target.type)
{
case 'text':
alert(target.value.length);//alerts length of input value
return;//this event is done, return
case 'radio':
alert('The radio button is ' + (target.checked ? '' : 'un') + 'checked');
return;
case 'password':
if (target.value.length < 8)
{
alert('The password is too short, add '+(8 - target.value.length)+'chars');
return;
}
var verifyPass = 'passIn_' + (target.id.match(/_1$/) ? '2' : '1');
verifyPass = document.getElementById(verifyPass);
if (verifyPass.value.length > 0 && target.value.length > 0 && verifyPass.value !== target.value)
{
alert('password confirmation failed');
}
}
return;
正如你所看到的,一吨的事件可以在一个单一的功能处理,结合1个事件侦听器。如果你直接绑定,你需要绑定大量的处理程序,可能需要编写几个函数,这些函数可能更难以维护,甚至更糟糕:使用户的网站缓慢。
好的,我现在已经做好准备睡觉了。我希望这能为你解决一些问题。阅读quirksmode上的网页,如果这个运球不是很清楚你可以在google上看一个关于事件代表团的教程,但是我希望我确实向你提供了我提供的代码的充分解释,并且为你提供了一些关于事件代表团的原因。正确的做事方式,以及为什么 - 在屏幕后面 - 大多数图书馆也是这样工作的。
如果您对包含无法理解的代码感到犹豫不决,可能会发现知道jQuery委托几乎所有事件,而不是直接绑定它们很有用。
我看到的onchange被直接插入到表单代码中,我觉得它是kludgy。 –
啊哈,是的,这是有点(不想听起来像一个twat)20世纪90年代;)。事件委托是恕我直言的一种方式:1事件处理器允许您处理整个页面的所有更改事件,而不会让客户端陷入困境;更重要的是:这很容易......一旦你掌握了它,真的很容易!最棒的是:它甚至不需要库(更不用说插件) –
我喜欢简单并且符合良好的编码习惯!我一直努力成为最好的编码员,即使我只是初级/中级! –
您需要侦听器来检测添加/删除的字符,并相应地更改计数器。所以,你必须要么使用一个按键侦听器,或者使用onchange
这里有一个例子: Twitter-like Textbox Character Count with inline alert
如果你使用jQuery,有一个插件,做到这一点。我已经在生产中使用它,并且效果很好。
与jQuery
$('input[name='the name of the input']').bind('keyup',function(){
$('#show').val($(this).length)
});
有提供此功能,并且各种配置各种jQuery插件
你可以一看:
http://youhack.me/2010/04/22/live-character-count-with-progress-bar-using-jquery/
http://qwertypants.me/counter/
希望,它会帮助你。
为什么你的“onchange”例子看起来像“kludgy”?他们应该是什么样子?除了它们的外观是否还有其他问题?如果我们没有看到原始代码,很难用更好的代码替换代码。 – 2012-06-22 18:02:08