2012-06-22 35 views
3

所以我想告诉用户他们有多少个字符是动态输入的。我在网上看到了几个使用“Onchange”或“OnKeyUp”的例子,但它们都是老例子,而且看起来很蹩脚。优雅的方式来计算textarea /输入框中的字符数

有没有更好的方法?也许某种绑定/分配的方法(可能不会正确使用这个术语)将值赋给一个变量,然后每次检查一次变化就进行检查?

+1

为什么你的“onchange”例子看起来像“kludgy”?他们应该是什么样子?除了它们的外观是否还有其他问题?如果我们没有看到原始代码,很难用更好的代码替换代码。 – 2012-06-22 18:02:08

回答

5

当你在谈论动态显示输入了多少个字符时,你需要事件,如onchangeonkeyup ......真的没有别的办法。

更重要的是:“将值分配给变量并检查每次更改是否已完成”除了通过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种说法,在这种情况下eevent - 无所谓你称之为。 (可能有多个参数,但是我们必须进入关闭状态,我会尽力并坚持这里的基础知识)。
事件对象在被大多数浏览器调用时将传递给处理函数,猜测哪个浏览器不会传递此对象?是的,我们的老朋友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委托几乎所有事件,而不是直接绑定它们很有用。

+0

我看到的onchange被直接插入到表单代码中,我觉得它是kludgy。 –

+1

啊哈,是的,这是有点(不想听起来像一个twat)20世纪90年代;)。事件委托是恕我直言的一种方式:1事件处理器允许您处理整个页面的所有更改事件,而不会让客户端陷入困境;更重要的是:这很容易......一旦你掌握了它,真的很容易!最棒的是:它甚至不需要库(更不用说插件) –

+0

我喜欢简单并且符合良好的编码习惯!我一直努力成为最好的编码员,即使我只是初级/中级! –

0

与jQuery

$('input[name='the name of the input']').bind('keyup',function(){ 
$('#show').val($(this).length) 
}); 
相关问题