代码之家  ›  专栏  ›  技术社区  ›  empi

限制文本区域中的行数

  •  34
  • empi  · 技术社区  · 17 年前

    我正在寻找一个可以限制行数的javascript(按行,我是指用户按键盘上的Enter键结束的一些文本),用户可以在文本区域中输入。我找到了一些解决方案,但它们根本不起作用,或者表现得很奇怪。 最好的解决方案是一个可以完成这项工作的jquery插件——类似于 CharLimit ,但它应该能够限制文本行数而不是字符数。

    8 回复  |  直到 7 年前
        1
  •  23
  •   marktucks    8 年前

    这个 可以 帮助(可能最好使用jquery、ondomready和不显眼地将keydown事件添加到文本区域),但在IE7和FF3中进行了测试:

    <html>
      <head><title>Test</title></head>
      <body>
        <script type="text/javascript">
          var keynum, lines = 1;
    
          function limitLines(obj, e) {
            // IE
            if(window.event) {
              keynum = e.keyCode;
            // Netscape/Firefox/Opera
            } else if(e.which) {
              keynum = e.which;
            }
    
            if(keynum == 13) {
              if(lines == obj.rows) {
                return false;
              }else{
                lines++;
              }
            }
          }
          </script>
        <textarea rows="4" onkeydown="return limitLines(this, event)"></textarea>
      </body>
    </html>
    

    *编辑-解释:如果按Enter键,它会捕捉到按键,如果文本区域中的行与文本区域中的行相同,它不会添加新行。否则它会增加行数。

    编辑第2页: 考虑到人们仍在使用这个答案,我想我会尽可能更新它来处理粘贴、删除和剪切。

    <html>
    
    <head>
        <title>Test</title>
        <style>
            .limit-me {
                height: 500px;
                width: 500px;
            }
        </style>
    </head>
    
    <body>
    <textarea rows="4" class="limit-me"></textarea>
    
    <script>
        var lines = 1;
    
        function getKeyNum(e) {
            var keynum;
            // IE
            if (window.event) {
                keynum = e.keyCode;
                // Netscape/Firefox/Opera
            } else if (e.which) {
                keynum = e.which;
            }
    
            return keynum;
        }
    
        var limitLines = function (e) {
            var keynum = getKeyNum(e);
    
            if (keynum === 13) {
                if (lines >= this.rows) {
                    e.stopPropagation();
                    e.preventDefault();
                } else {
                    lines++;
                }
            }
        };
    
        var setNumberOfLines = function (e) {
            lines = getNumberOfLines(this.value);
        };
    
        var limitPaste = function (e) {
            var clipboardData, pastedData;
    
            // Stop data actually being pasted into div
            e.stopPropagation();
            e.preventDefault();
    
            // Get pasted data via clipboard API
            clipboardData = e.clipboardData || window.clipboardData;
            pastedData = clipboardData.getData('Text');
    
            var pastedLines = getNumberOfLines(pastedData);
    
            // Do whatever with pasteddata
            if (pastedLines <= this.rows) {
                lines = pastedLines;
                this.value = pastedData;
            }
            else if (pastedLines > this.rows) {
                // alert("Too many lines pasted ");
                this.value = pastedData
                    .split(/\r\n|\r|\n/)
                    .slice(0, this.rows)
                    .join("\n ");
            }
        };
    
        function getNumberOfLines(str) {
            if (str) {
                return str.split(/\r\n|\r|\n/).length;
            }
    
            return 1;
        }
    
        var limitedElements = document.getElementsByClassName('limit-me');
    
        Array.from(limitedElements).forEach(function (element) {
            element.addEventListener('keydown', limitLines);
            element.addEventListener('keyup', setNumberOfLines);
            element.addEventListener('cut', setNumberOfLines);
            element.addEventListener('paste', limitPaste);
        });
    </script>
    </body>
    </html>
    
        2
  •  15
  •   Maciej    15 年前

    如何使用jquery:

    绑定到TextArea的KeyDown事件。

    function limitTextareaLine(e) {
        if(e.keyCode == 13 && $(this).val().split("\n").length >= $(this).attr('rows')) { 
            return false;
        }
    }
    
        3
  •  4
  •   Daniel M. Melo    12 年前

    此解决方案有效:

    <script type="text/javascript">
        function limitTextarea(textarea, maxLines, maxChar) {
            var lines = textarea.value.replace(/\r/g, '').split('\n'), lines_removed, char_removed, i;
            if (maxLines && lines.length > maxLines) {
                lines = lines.slice(0, maxLines);
                lines_removed = 1
            }
            if (maxChar) {
                i = lines.length;
                while (i-- > 0) if (lines[i].length > maxChar) {
                    lines[i] = lines[i].slice(0, maxChar);
                    char_removed = 1
                }
                if (char_removed || lines_removed) {
                    textarea.value = lines.join('\n')
                }
            }
        }
    </script>
    

    文本区域将是

    <asp:TextBox ID="myWishTB" runat="server" Height="185px" TextMode="MultiLine" 
                 Style="overflow: auto;" Width="95%" 
                 onkeyup="limitTextarea(this,10,80)">
    </asp:TextBox>
    

    在常规HTML中:

    <textarea id="textareaID" onkeyup="limitTextarea(this,5,100)" cols="20" rows="5">   </textarea>
    
        4
  •  3
  •   alphadogg    17 年前

    给定文本块的可见/显示行数因浏览器、使用的字体等的不同而不同。您必须至少设置特定的字体和字体大小,才能半可靠地计数显示行。

    更新:我看到了编辑。那么像kevchardders代码之类的东西应该对你有用。您将需要计算字符和\r\n的JS,并根据用户定义的限制进行检查。另外,如果您不使用他的脚本,请确保使用一个涉及时间间隔检查和/或文本区域的onkeydown/onkeyup事件的脚本。这可能就是为什么您测试过的一些脚本看起来“行为怪异”的原因。

        5
  •  3
  •   Cesar Morillas Barrio    15 年前

    (使用jquery完成)。它不是完美的,但很注重包装。不只删除行结尾(\n)。
    jquery scroll事件在mozilla和firefox中存在问题,如果textfarea中的css overflow属性不是auto,则移除相应的行并将overflow设置为hidden。可以帮助CSS调整大小:无和固定高度。

    $('#textarea').scroll(function () {
        $(this).css("overflow", "hidden");      /* for the mozilla browser problem */
        $(this).animate({scrollTop: $(this).outerHeight()});
        while ($(this).scrollTop() > 0) {       /* for the copy and paste case */               
            lines=$(this).val().slice(0,-1);
            $(this).val(lines);
        }
        $(this).css("overflow", "auto");        /* For the mozilla browser problem */
    });
    
        6
  •  2
  •   user158456    12 年前

    jquery示例。这对打字和粘贴都有效。

      //Limit to # of rows in textarea or arbitrary # of rows
      $('#yourtextarea').bind('change keyup', function(event) {
        //Option 1: Limit to # of rows in textarea
        rows = $(this).attr('rows');
        //Optiion 2: Limit to arbitrary # of rows
        rows = 6;
    
        var value = '';
        var splitval = $(this).val().split("\n");
    
        for(var a=0;a<rows && typeof splitval[a] != 'undefined';a++) {
          if(a>0) value += "\n";
          value += splitval[a];
        }
        $(this).val(value);
      });
    
        7
  •  1
  •   northland_denmark    17 年前

    这与使用jquery的伊万的答案基本相同。我为自己的一个项目测试过它;似乎工作得很好。

    <script type="text/javascript" charset="utf-8">
      $(function() 
      {
        function getLines(id)
        {
          return $('#' + id).val().split("\n").length
        }
    
      $('#testing').keyup(function() 
      {
        var allowedNumberOfLines = 4;
    
        if(getLines('testing') > allowedNumberOfLines)
        {
          modifiedText = $(this).val().split("\n").slice(0, allowedNumberOfLines);
          $(this).val(modifiedText.join("\n"));
        }
      });
    });
    </script>
    
        8
  •  0
  •   vellotis    14 年前

    我将它扩展了一点,以便在不使用手动换行符的情况下检测甚至溢出。这适用于具有“溢出:隐藏”的固定大小文本区域。

    目前,我的解决方案使字体变小,如果它不适合文本区域。如果可能的话,再放大一次。

    var keynum, allowedLines = 5, defaultFontSize = 13/*px*/;
    
    $(document).ready(function() {
        $("textarea").keydown(function(e, obj) {
            if(window.event)
                keynum = e.keyCode;
            else if (e.which)
                keynum = e.which;
    
            if (keynum == 13 && allowedLines <= $(this).val().split("\n").length)
                return false;
        });
        $("textarea").keyup(function(e, obj) {
            // Avoid copy-paste
            if (allowedLines < $(this).val().split("\n").length) {              
                lines = $(this).val().split("\n").slice(0, allowedLines);
                $(this).val( lines.join('\n') );
            }
    
            // Check overflow
            if ((this.clientHeight < this.scrollHeight)) {
                while ((this.clientHeight < this.scrollHeight)) {
                    currFontSize = $(this).css('font-size');
                    finalNum = parseFloat(currFontSize, 11);
                    stringEnding = currFontSize.slice(-2);
                    $(this).css('font-size', (finalNum-1) + stringEnding);
                }
            } else if ($(this).css('fontSize') != defaultFontSize+'px')  {
                while ($(this).css('font-size') != defaultFontSize+'px') {
                    // First lets increase the font size
                    currFontSize = $(this).css('font-size');
                    finalNum = parseFloat(currFontSize, 11);
                    stringEnding = currFontSize.slice(-2);
                    $(this).css('font-size', (finalNum+1) + stringEnding);
                    // lets loop until its enough or it gets overflow again
                    if(this.clientHeight < this.scrollHeight) {
                        // there was an overflow and we have to recover the value
                        $(this).css('font-size', currFontSize);
                        break;
                    }
                }
            }
        });
    });