3

所以我想动态地告诉用户他们输入了多少个字符。我在网上看到了几个使用“Onchange”或“OnKeyUp”的例子,但它们都是旧例子,而且看起来有点笨拙。

有没有更好的办法?也许某种绑定/分配(可能未正确使用该术语)值到变量的方法,然后在每次进行更改时进行检查?

4

5 回答 5

6

当您谈论动态显示已键入的字符数时,您将需要事件,例如onchangeonkeyup......真的没有其他方法。

更重要的是:“将值分配给变量并在每次进行更改时检查”还有其他方式,但通过onchange您将知道您需要检查什么以及何时检查?

一种快速、简单的方法:

document.getElementById('aninputId').onchange= function(e)
{
    console.log(this.value.length);//or alert(); do with this value what you want
};

要记住的重要一点是,如果您要处理很多元素,您可能需要考虑委派事件。在这里,您可以找到一个类似(不重复)的问题,其中包含 2 个处理事件委托的答案。谷歌它以了解有关此强大功能的更多信息!


更新(带小提琴)

好的,我设置了这个快速小提琴作为使用事件委托的示例。我用onchange了,所以在失去焦点之前不会显示长度,有一些注释告诉你代码的作用,但是写得比较仓促。如果您对此示例有任何疑问,请告诉我。

PS:如果你想实时改变长度,只需更换

mainDiv.addEventListener('onchange',showLength,false);

mainDiv.addEventListener('keyup',showLength,false);

仅此而已!


更新2

回应您的最后评论:不,该代码不起作用。该alert(e);行将尝试提醒event object,因此您只会看到 '[object object]',如果不是undefined在 IE 上。

为了帮助您理解我的 jsfiddle 中的代码是做什么的,我将逐步分解并通过它:

在我的示例中,输入字段(只有 1 个,但可能有 100 个)都是主 div 元素的子项#allInputs。所以首先,我们得到一个对该元素的引用:

var mainDiv = document.getElementById('allInputs');//Here's where we'll listen for events

然后,我们想要一个附加到该 div 的事件侦听器。由于 IE 中的事件冒泡,以及所有其他浏览器中的事件捕获,在此元素内触发的所有事件都将通过 div。这里有一些图表可能会阐明我的意思。这是事件委托的关键概念。一旦你得到了这个,剩下的就很容易了。

现在,回到监听事件:addEventListener做它在锡上所说的:它附加到一个元素并监听在该元素内触发/调度的事件。如果这些事件中的任何一个属于指定类型,它就会调用一个函数。这个函数就是所谓的回调,或者 - 在这种情况下 - 事件处理程序。与往常一样,IE 并不像所有其他浏览器一样工作,所以首先我们检查该addEventHandler方法是否对我们可用。

if (!(mainDiv.addEventListener))
{//if not: this is the IE way
    mainDiv.attachEvent('onfocusout',showLength);
}
else
{
    mainDiv.addEventListener('change',showLength,false);
}

在这两种情况下,第一个参数都是一个字符串,说明我们要监听的事件类型,在大多数情况下,从事件类型的名称中addEventListener删除。onIE,又是固执的不支持onchange委托的事件(它不会冒泡),我们通过监听另一个事件来解决这个问题:IE 自己的 onfocusout 事件(如果输入元素失去焦点,它很可能是用于输入,并且有一个新值。这使得检查值长度的正确时机。
addEventListener有第三个参数,用于捕获事件,在这种情况下这无关紧要,但是在 quirksmode (上面的链接)上,你可以阅读有关此主题的更多信息,我建议您这样做。

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 事件被调度,然后寻找它们的target元素,IE 事件在元素处调度,并从它们的源冒泡。——我飘了。

在这个阶段我们知道什么?我们需要知道的一切,真的。我们知道触发了什么事件(e.type会告诉我们 - 在这种情况下是更改或聚焦)。我们什么元素已经改变/失去焦点,并且在变量中有对该元素的引用target,所以我们可以得到它的值(target.value),它的 id(target.id),更重要的是:我们可以检查我们是否想做进一步的事情:

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 的页面,如果这个运球对您来说不是很清楚,请在谷歌上搜索有关事件委托的教程,但我希望我确实为您提供了对我提供的代码的充分解释,并让您了解事件委托的原因正确的做事方式,以及为什么——在幕后——大多数图书馆也以这种方式工作。
如果您真的对包含您无法理解的代码犹豫不决,您可能会发现知道 jQuery 委托几乎所有事件而不是直接绑定它们很有用。

于 2012-06-22T18:02:01.907 回答
1

您需要一个侦听器来检测添加/删除的字符,并相应地更改计数器。所以你必须要么使用一个关键的监听器,要么使用onchange

这是一个示例: 带有内联警报的类似 Twitter 的文本框字符计数

于 2012-06-22T18:03:43.823 回答
0

如果你使用 jQuery,有一个插件可以做到这一点。我已经在生产中使用它并且效果很好。

http://cssglobe.com/post/7161/jquery-plugin-simplest-twitterlike-dynamic-character-count-for-textareas

于 2012-06-22T18:11:41.893 回答
0

有各种提供此功能和各种配置的 jquery 插件
您可以查看:

http://youhack.me/2010/04/22/live-character-count-with-progress-bar-using-jquery/

http://qwertypants.me/counter/

希望,它会帮助你。

于 2012-06-22T18:15:37.380 回答
0

用jQuery

$('input[name='the name of the input']').bind('keyup',function(){
 $('#show').val($(this).length)
});
于 2012-06-22T18:12:25.650 回答