鉴于textarea,有没有办法根据行数来限制长度?

时间:2011-09-22 18:02:44

标签: jquery css

我有一个textarea字段,我希望用户能够输入不超过3行。

这可能吗?

2 个答案:

答案 0 :(得分:3)

小提琴:http://jsfiddle.net/nvLBZ/1/

我刚刚(2小时)创建了一个脚本,总是将文本区域的高度限制为3行。

  1. 为特定文本区域计算字符的最大可能宽度(如果之前尚未计算)。
  2. 计算每行的最小单词数。
  3. 克隆textarea,以测试是否有必要继续使用该功能。当输入有效时,函数返回时不会中断用户。

  4. 否则,克隆的textarea将用作参考,并删除用户的textarea。出于性能原因,用户的textarea也是暂时不可见的。

  5. 使用有效的方法填充textarea:已知小于textarea宽度的块将添加到textarea中。
  6. 当添加的块超过最大大小时,将单独删除最后一个字符,直到最终达到最大行限制。
  7. 恢复默认值。
  8. 下面的代码,代码在底部实现($(document).ready(...))。

    (function(){        
        var wordWidthMappers = {};
        function checkHeight(textarea, maxLines){
            if(!(textarea instanceof $)) return; /*JQuery is required*/
            if(isNaN(maxLines) || !isFinite(maxLines) || maxLines == 0) return;
            var areaWidth = textarea.width();
            var oldHeight = textarea.css("height");
            var oldOverflow = textarea.css("overflow-y");
            var lineHeight = parseFloat(textarea.css("line-height"));
            var maxTxtHeight = maxLines*lineHeight + "px";
    
            /*Calculations for an efficient determination*/
            var fontstyles = "font-size:"+textarea.css("font-size");
            fontstyles += ";font-family:"+textarea.css("font-family");
            fontstyles += ";font-weight:"+textarea.css("font-weight");
            fontstyles += ";font-style:"+textarea.css("font-style");
            fontstyles += ";font-variant:"+textarea.css("font-variant");
            var wordWidth = wordWidthMappers[fontstyles];
            if(!wordWidth){
                var span = document.createElement("span");
                span.style.cssText = fontstyles+";display:inline;width:auto;min-width:0;padding:0;margin:0;border:none;";
                span.innerHTML = "W"; //Widest character
                document.body.appendChild(span);
                wordWidth = wordWidthMappers[fontstyles] = $(span).width();
                document.body.removeChild(span);
            }
    
            textarea = textarea[0];
            var temparea = textarea.cloneNode(false);
            temparea.style.visibility = "hidden";
            temparea.style.height = maxTxtHeight;
            temparea.value = textarea.value;
            document.body.appendChild(temparea);
            /*Math.round is necessary, to deal with browser-specific interpretations
              of height*/
            if(Math.round(temparea.scrollHeight/lineHeight) > maxLines){
                textarea.value = "";
                textarea.style.visibility = "hidden";
                if(oldOverflow != "scroll") textarea.style.overflowY = "hidden";
                textarea.style.height = maxTxtHeight;
                var i = 0;
                var textlen = temparea.value.length;
                var chars_per_line = Math.floor(areaWidth/wordWidth);
                while(i <= textlen){
                    var curLines = Math.round(textarea.scrollHeight/lineHeight);
                    if(curLines <= maxLines){
                        var str_to_add = temparea.value.substring(i, i+chars_per_line);
                        var nextLn = str_to_add.indexOf("\n");
                        if(nextLn > 0) str_to_add = str_to_add.substring(0, nextLn);
                        else if(nextLn == 0) str_to_add = "\n";
                        i += str_to_add.length;
                        textarea.value += str_to_add;
                    } else if(curLines > maxLines){
                        textarea.value = textarea.value.substring(0, textarea.value.length-1);
                        i--;
                        if(Math.round(textarea.scrollHeight/lineHeight) <= maxLines) break;
                    }
                }
                textarea.style.visibility = "visible";
                textarea.style.height = oldHeight;
                textarea.style.overflowY = oldOverflow;
            }
            temparea.parentNode.removeChild(temparea);
        }
    
        $(document).ready(function(){/* Add checker to the document */
            var tovalidate = $("#myTextarea");
            tovalidate.keyup(function(){
                /*Add keyup event handler. Optionally: onchange*/
                checkHeight(tovalidate, 3);
            });
        });
    })();
    

答案 1 :(得分:0)

可能?也许。

你如何测量线?你是否包括自动换行?如果是这样,那么你将无法可靠地这样做。

如果您只将换行符计为“行”,那么您可以随时将一个按键事件添加到textarea并检查该区域中的中断次数,并且不允许超过三次。