给定一个文本区域,有没有办法根据行数限制长度?

Posted

技术标签:

【中文标题】给定一个文本区域,有没有办法根据行数限制长度?【英文标题】:Given a textarea, is there a way to restrict length based on # of lines? 【发布时间】:2011-11-23 01:50:27 【问题描述】:

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

这可能吗?

【问题讨论】:

你看过了吗:***.com/questions/556767/… codingforums.com/archive/index.php/t-71233.html 如何测量线条?你计算由于换行而创建的新行吗? 相关话题?:***.com/questions/1760629/… 【参考方案1】:

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

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

    为特定文本区域计算字符的最大可能宽度(如果之前尚未计算)。 计算每行的最少字数。

    克隆文本区域,以测试是否需要继续使用该功能。当输入有效时,函数返回而不中断用户。

    否则,克隆的文本区域被用作参考,用户的文本区域被擦除。出于性能原因,用户的文本区域也是暂时不可见的。

    使用一种有效的方法填充文本区域:将已知小于文本区域宽度的块添加到文本区域中。 当添加的块超过最大大小时,将单独删除最后一个字符,直到最终达到最大行数限制。 恢复默认设置。

代码如下,代码在底层实现($(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);
        );
    );
)();

【讨论】:

【参考方案2】:

可能吗?可能是。

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

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

【讨论】:

不幸的是,使用这种方法(计算有多少字符组成三行)会产生不一致的结果,因为向下的文本框不使用等宽字体(填充的 m 会比填充的 i 长)。您还遇到用户输入 a[newline]b[newline]c[newline]d[newline] 的问题。 @Joseph - 你是对的。我更新了。我认为自动换行会很重要,等等。

以上是关于给定一个文本区域,有没有办法根据行数限制长度?的主要内容,如果未能解决你的问题,请参考以下文章

IE中的文本区域最大长度

文本区域字符限制

Ruby on Rails 中文本区域的最大长度

文本区域的最大长度在 IE 中不起作用

Android 应用 (Cordova) 上的文本区域中的字数超出限制

严格限制 textarea Angular 中的行数