带有负数和强制执行的文本区域计数器/倒计时

Textarea counter / countdown with negative numbers and enforcement

我一直致力于为 TEXTAREA 字段添加字符计数器。网上有很多解决此任务的方法。

"Stop-at-Zero" 解
我遇到的问题是几乎所有解决方案都在 0 时终止用户输入。我猜这很有效,但就用户友好性而言并不是最佳选择。例如,如果用户将文本粘贴到 TEXTAREA 中,并且文本超出了字段的限制,这种停在零的解决方案将突然截断多余的文本。然后,用户必须努力寻找丢失的内容,然后编辑他们的消息、提交第二份表格或其他一些负担。

"Negative Character Count" 解
其他解决方案允许用户输入他们想要的所有内容。字符计数器将从正变为负。这些计数器的问题是缺乏执行力:即使字符数为负数,它们也允许用户提交表单。

Twitter 解决方案
我认为推特是对的。他们让用户输入他们想要的所有内容,并用负字符数(和彩色背景,我不需要)突出显示多余的文本。他们在计数为负时禁用提交按钮。

我的(不完整)解决方案
使用我通过 Google 找到的第三方代码,我设计了一个字符计数器,它在计数方面工作得很好。但是作为 JS 的新手,我无法编写执行部分的代码。

这是我的问题:
当计数器为负数时,如何获取阻止提交表单的代码?

HTML

<form action="" method="post">

<div>
<textarea name="comments" id="comments" cols="50" rows="10"></textarea>
</div>

<div>
<input type="submit">
</div>

</form>

CSS

form div {
    position: relative;
}

form .counter {
    position: absolute;
    left: 300px;
    bottom: -25px;
    font-size: 25px;
    font-weight: bold;
    color: #ccc;
    }

form .warning {color: orange;}

form .exceeded {color: red;}

JavaScript

<script src="/js/jquery.js"></script>

<script>

(function($) {

    $.fn.charCount = function(options){

        // default configuration properties
        var defaults = {    
            allowed: 100,       
            warning: 25,
            css: 'counter',
            counterElement: 'span',
            cssWarning: 'warning',
            cssExceeded: 'exceeded',
            counterText: ''
        }; 

        var options = $.extend(defaults, options); 

        function calculate(obj){
            var count = $(obj).val().length;
            var available = options.allowed - count;
            if(available <= options.warning && available >= 0){
                $(obj).next().addClass(options.cssWarning);
            } else {
                $(obj).next().removeClass(options.cssWarning);
            }
            if(available < 0){
                $(obj).next().addClass(options.cssExceeded);
            } else {
                $(obj).next().removeClass(options.cssExceeded);
            }
            $(obj).next().html(options.counterText + available);
        };

        this.each(function() {              
            $(this).after('<'+ options.counterElement +' class="' + options.css + '">'+ options.counterText +'</'+ options.counterElement +'>');
            calculate(this);
            $(this).keyup(function(){calculate(this)});
            $(this).change(function(){calculate(this)});
        });

    };

})(jQuery);

</script>

<script>
    $(document).ready(function(){   
        $("#comments").charCount();
    });
</script>

https://jsfiddle.net/nyc212/sk5kfopw/

我会尝试使用 disabled 属性禁用提交按钮,或者使用 e.preventDefault 阻止表单提交。我更新了你的 fiddle...只是取消注释其中一个选项

https://jsfiddle.net/sk5kfopw/1/

我已经修改了您的插件,将提交按钮作为第一个参数。 如果你想让它更有活力:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <title></title>
 <style>
  form div {
   position: relative;
  }

  form .counter {
   position: absolute;
   left: 300px;
   bottom: -25px;
   font-size: 25px;
   font-weight: bold;
   color: #ccc;
  }

  form .warning {
   color: orange;
  }

  form .exceeded {
   color: red;
  }
 </style>
 <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
 <script>
  (function($) {

   $.fn.charCount = function(btnsub, options){
   
    this.btnsub = btnsub;
        
    // default configuration properties
    var defaults = { 
     allowed: 100,  
     warning: 25,
     css: 'counter',
     counterElement: 'span',
     cssWarning: 'warning',
     cssExceeded: 'exceeded',
     counterText: ''
    }; 
   
    var options = $.extend(defaults, options); 
  
    function calculate(obj,btnsub){
    
     btnsub.attr("disabled", "disabled");

     var count = $(obj).val().length;
     var available = options.allowed - count;
     if(available <= options.warning && available >= 0){
      $(obj).next().addClass(options.cssWarning);
     } else {
      $(obj).next().removeClass(options.cssWarning);
     }
     if(available < 0){
      $(obj).next().addClass(options.cssExceeded);
     } else {
      $(obj).next().removeClass(options.cssExceeded);
      btnsub.removeAttr("disabled");
     }
     
     $(obj).next().html(options.counterText + available);
    };
    
    this.each(function() {     
     $(this).after('<'+ options.counterElement +' class="' + options.css + '">'+ options.counterText +'</'+ options.counterElement +'>');
     
     calculate(this, btnsub);

     $(this).keyup(function(){calculate(this,btnsub)});
     $(this).change(function(){calculate(this,btnsub)});
    });
   
   };

  })(jQuery);

  $(document).ready(function(){ 
   $("#comments").charCount($("#btnsub"));
  });

 </script>
</head>
<body>
 <form method="post">

  <div>
   <textarea name="comments" id="comments" cols="50" rows="10"></textarea>
  </div>

  <div>
   <input type="submit" id="btnsub">
  </div>

 </form>
</body>
</html>