计算输入字符 - 使用 onkeyup 还是 onkeydown?

5
我需要设置用户的最大字符输入,类似于stackoverflow.com的方式。我计划使用JavaScript向用户提供反馈并计算字符数。只有不超过最大字符数的提交才被允许。我不打算使用xhtml输入属性来限制此数量,因为只要它们没有被提交,就可以允许字符溢出。在后端,我将只是将mysql中的varchar字段设置为charmax。
问题是,如何计算字符输入?我应该基于onkeydown()还是onkeyup()进行计算?我不太确定为什么有两个函数,因为按下的键必须弹起,所以我应该使用哪一个来计数?

你实际上应该只是使用一个插件,比如http://roy-jin.appspot.com/jsp/textareaCounter.jsp。但是回答你的问题,你应该绑定keyUp事件,以及其他事件(如paste),并且可能应该设置0毫秒的超时以便更新文本。 - Alex Churchill
这个问题似乎与编程有关。 - hmakholm left over Monica
4个回答

12

HTML:

<input type='text' id='text'/>

JS:

->

JavaScript:

function textLength(value){
   var maxLength = 144;
   if(value.length > maxLength) return false;
   return true;
}

document.getElementById('text').onkeyup = function(){
     if(!textLength(this.value)) alert('text is too long!');
}

这里是一个演示fiddle: http://jsfiddle.net/maniator/L2LRK/


<input type="text"> - user1385191
1
@Matt -- 我没有为输入设置类型... 如果你觉得需要的话,我可以添加一个... - Naftali
问题是,我如何计算字符输入,我是基于onkeydown()还是onkeyup()?答案应该是否定的。有更简单和更可靠的方法来做到这一点。例如@GolezTrol的答案。 - ian

9
使用document.getElementById('YourInputBoxId').value.length来获取文本的长度。
不要使用键盘事件来跟踪字符数。Ctrl+V是一个按键(或两个),但它可能导致你的文本增长到几兆字节的大小。:) 您可以使用这些事件来更新带有当前字符数的标签。
除了onkeyup,您还可以使用oninput事件,在输入框中键入时触发。
并且请记住,始终在服务器上进行检查。Javascript可能会失败或被故意禁用。您的服务器应始终执行必要的检查。尽管我相信MySQL将自动截断过大的文本...
一个很好的替代方案是设置输入的maxlength属性。这样,即使没有javascript,也会强制执行最大长度。然后,您可以删除该标志并从javascript添加必要的事件。这样,您将拥有适用于javascript浏览器的可用解决方案,同时对于非javascript浏览器,将有更严格的检查,我认为这比根本没有检查要好。

谢谢,我可以使用它来获取值。SO在反馈显示中使用onkeyup(),但实际字符显示在onkeydown()上,所以如果您想要详细了解,onkeydown()更准确。 - user656925
@Chris .value.length 在 keyDown 事件中不总是会被更新(或者至少在我大约5个月前做这件事时在 Chrome 上没有),这就是为什么通常绑定 keyUp 的原因。而且,谁在进行全面的 downvotes 应该停止或给出解释。我已经将两个回答都投票回到了0,因为它们都是完全好的答案。 - Alex Churchill
谢谢。我认为有些混淆,因为我写了“不要使用键盘事件”。我以为Chris的意思是计算这些事件的调用次数来获取字符数,而不是获取框中文本的实际长度。 - GolezTrol
添加了关于 oninput 的一点说明。 - GolezTrol

2
我发现了你建议中的错误。以下是我的测试模式:
如果限制最大字符数为05个字符。
测试值:123456,ABCDEF
1:使用键盘,正常输入文本
对于123456,6将被删除;
对于ABCDEF,F将被删除。
结果:OK
2:使用键盘,从其他地方复制并粘贴123456和ABCDEF
对于123456,粘贴(Ctrl V):“123456123456” => 456123456将被删除;
对于ABCDEF,粘贴(Ctrl V):“ABCDEFABCDEF” => DEFABCDEF将被删除。
结果:OK
3:使用鼠标,从其他地方复制并粘贴123456和ABCDEF
对于123456,粘贴(右键单击+粘贴):“123456123456” => 不会删除任何字符;
对于ABCDEF,粘贴(右键单击+粘贴):“ABCDEFABCDEF” => 不会删除任何字符。
结果:FALSE;
4:使用鼠标,从其他地方复制并粘贴123456和ABCDEF,然后输入其他内容
对于123456,粘贴(右键单击+粘贴):“123456123456” => 不会删除任何字符,使用键盘输入“123” => 所有文本都将被删除。
对于ABCDEF,粘贴(右键单击+粘贴):“ABCDEFABCDEF” => 不会删除任何字符,使用键盘输入“ABC” => 所有文本都将被删除。
结果:FALSE;
我在同一个函数中遇到了相同的错误。在我的函数中,这个模式对所有情况都是错误的。以下是我的代码:jsfiddle 我在互联网上找到了这个函数,很抱歉我忘记了来源,如果你是所有者,请原谅我在此公开它。
HTML:

//Count content
  maxL = 2000;
  var bName = navigator.appName;

  function taLimit(taObj) {
    if (taObj.value.length == maxL) return false;
    return true;
  }

  function taCount(taObj, Cnt) {
    objCnt = createObject(Cnt);
    objVal = taObj.value;
    if (objVal.length > maxL) objVal = objVal.substring(0, maxL);
    if (objCnt) {
      if (bName == "Netscape") {
        objCnt.textContent = maxL - objVal.length;
      } else {
        objCnt.innerText = maxL - objVal.length;
      }
    }
    return true;
  }

  function createObject(objId) {
    if (document.getElementById) return document.getElementById(objId);
    else if (document.layers) return eval("document." + objId);
    else if (document.all) return eval("document.all." + objId);
    else return eval("document." + objId);
  } //End Count content
You have <b><label id="myCounter">2000</label></b> characters left
<br/>
<textarea class="inputtextfield" onKeyPress="return taLimit(this)" onKeyUp="return taCount(this,'myCounter')" id="content" name="content" rows=7 wrap="physical" cols=40></textarea>

我很困惑如何修复我的错误。


1

有两个函数因为有两个不同的事件。例如,如果您想知道某人何时按下Ctrl+Enter,则需要确切地知道每个键何时按下和释放。

在您的情况下(达到限制时显示警告),我会使用keydown,因为那是首先发生的,这样您就可以在用户超过X个字符的那一刻知道。如果您使用keyup,用户可能会按下几秒钟的键而没有看到任何消息。

要计算字符数,您可以执行以下操作:

document.getElementById("myInput").value.length

哇哦...我要放一个“复活节彩蛋”进去 - user656925

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接