【问题标题】:Capture *all* display-characters in JavaScript?在 JavaScript 中捕获 *all* 显示字符?
【发布时间】:2010-04-21 16:19:36
【问题描述】:

我最近收到了一个不寻常的请求,我遇到了最困难的问题,涉及在文本框中输入时捕获所有显示字符。设置如下:

我有一个 ma​​xlength 为 10 个字符的文本框。当用户尝试输入超过 10 个字符时,我需要通知用户他们的输入超出了字符数限制。

最简单的解决方案是将 ma​​xlength 指定为 11,测试每个 keyup 的长度,然后截断回 10 个字符,但这个解决方案似乎有点笨拙.我更喜欢在 keyup 之前捕获字符,并根据它是否是显示字符,向用户显示通知并阻止默认操作。

由于我们处理大量国际数据,因此白名单将具有挑战性。

我玩过 keydownkeypresskeyup 的所有组合,阅读 event.keyCodeevent.charCodeevent.which,但我找不到适用于所有浏览器的单一组合。我能做到的最好的方法是在 >=IE6、Chrome5、FF3.6 中正常工作,但在 Opera 中失败:

注意:以下代码使用 jQuery。

$(function(){
  $('#textbox').keypress(function(e){
    var $this = $(this);
    var key = ('undefined'==typeof e.which?e.keyCode:e.which);
    if ($this.val().length==($this.attr('maxlength')||10)) {
      switch(key){
        case 13: //return
        case 9:  //tab
        case 27: //escape
        case 8:  //backspace
        case 0:  //other non-alphanumeric
          break;
        default:
          alert('no - '+e.charCode+' - '+e.which+' - '+e.keyCode);
          return false;
      };
    }
  });
});

我承认我正在做的事情可能是过度设计了解决方案,但现在我已经投入其中,我想知道一个解决方案。

【问题讨论】:

  • 另外,不要忘记用户正在将数据粘贴到您的控件中。
  • 感谢您的提示。我已经考虑过实现一个 onPaste 处理程序,但是,考虑到输入的上下文,用户粘贴到其中的可能性很小(更不用说对 onPaste 的支持有多么参差不齐)。

标签: javascript keyboard-events jquery-events keycode


【解决方案1】:

最简单的解决方案是将 maxlength 指定为 11,测试每个 keyup 的长度,然后截断回 10 个字符,但这个解决方案似乎有点笨拙。

它也很容易被剪切/粘贴、拖放、右键单击撤消/重做等打败。没有可靠的方法来获取除轮询之外的所有潜在输入。

为什么不将maxlength 设置为 10,让浏览器正确执行限制,并且如果有 另一个 尝试按键,则只显示警告?您无需阻止任何默认操作,因为浏览器已经在处理长度问题,因此您需要进行的密钥检查量更少。

<input id="x" maxlength="10"/>
<div id="x-warning" style="display: none;">can't type any more!</div>
<script type="text/javascript">
    function LengthMonitor(element, warning) {
        element.onkeypress= function(event) {
            if (event===undefined) event= window.event;
            var code= 'charCode' in event? event.charCode : 'which' in event? event.which : event.keyCode;
            var full= element.value.length===element.maxLength;
            var typed= !(code<32 || event.ctrlKey || event.altKey || event.metaKey);
            warning.style.display= (full & typed)? 'block' : 'none';
        };
        element.onblur= function() {
            warning.style.display= 'none';
        };
    }

    LengthMonitor(document.getElementById('x'), document.getElementById('x-warning'));
</script>

【讨论】:

  • 在某种程度上有效,但 charCode 在 IE 和 Opera 中是不受支持的属性。
  • 是的,对于这些浏览器,您可以尝试回退到 whichkeyCode。不幸的是,keypress 很不稳定(例如,在 IE 中,您无法区分 page-up 和 !)。如果您想可靠地执行此操作,则必须改为捕获 keydown 并保留一个表示或不表示真实字符的键码列表。没什么好玩的。
【解决方案2】:

由于您已经在使用 JQuery,.validate() 非常适合表单。只需为您的领域设置一个 maxlength 规则,您就可以开始了。例如

$("form[name='myform']").validate({
    rules: {
        myfield: {required:true, maxlength:10}
    }
});

【讨论】:

  • 感谢您的提示,但这并不能解决手头的问题。 10 个字符是硬性限制,如果用户尝试超出硬性限制,我需要进行现场测试。
【解决方案3】:

在我正在开发的一个网络应用程序中,我遇到了类似的情况,我需要在用户将数据输入输入时实时向他们提供反馈。

老实说,我想出的最佳解决方案就是使用 setTimeout 定期轮询输入框。我做了一些测试以在响应性和效率之间找到一个很好的平衡点(我认为大约 400 毫秒)。

它工作得很好,并且比尝试将每个场景的事件处理程序(按键按下、更改等)组合在一起要好得多。

它不像我想要的那样优雅,但它确实有效。

如果你真的想这样做,我会实时观察输入,检查它的长度。如果超过限制,砍掉它并提醒用户。

这当然不能替代其他验证。

我也认为这可能是不必要的。我想这很好,但大多数网站都有硬限制和提交验证。

【讨论】:

    【解决方案4】:

    当用户超过限制时向用户显示一条消息,但不截断他们的输入如何?您可以使用 onsubmit 事件阻止提交,并且用户将永远不会遇到最大长度或瞬态输入的糟糕体验。您可以用红色突出显示该框或显示一个图标,以真正将要点带回家。

    但是,这都是客户端,所以如果你真的需要验证输入,那必须内置到提交目标的服务器端逻辑中(在表单的情况下)。

    或者,如果这是实时发生的,则将逻辑链接到由按键事件设置的变量。如果超出长度限制,则显示错误消息,不要截断,也不要更新私有变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-09
      • 1970-01-01
      相关资源
      最近更新 更多