Javascript 限制文本区域中的行数

Javascript 限制文本区域中的行数,javascript,jquery,textarea,Javascript,Jquery,Textarea,我正在寻找一个javascript,它可以限制用户能够在textarea中输入的行数(通过行,我指的是用户在键盘上按enter键结束的一些文本)。我已经找到了一些解决方案,但它们根本不起作用,或者表现得很怪异。 最好的解决方案是一个jquery插件,它可以完成这项工作-类似于,但它应该能够限制文本行数而不是字符数。给定文本块的可见/显示行数会随着浏览器、使用的字体等的不同而变化。您必须至少设置特定的字体和字体大小,能够半可靠地计数显示行 更新:我看到了编辑。然后像kevchadders这样的代码

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

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

更新:我看到了编辑。然后像kevchadders这样的代码应该可以很好地为您服务。您需要计算字符和'\r\n'的js,并根据用户定义的限制进行检查。此外,如果您不使用他的脚本,请确保您使用的脚本涉及时间间隔检查和/或文本区域的onKeyDown/onkeydup事件。这可能是您测试过的某些脚本似乎“行为异常”的原因。

这可能会有所帮助(可能最好使用jQuery、onDomReady并悄悄地将keydown事件添加到textarea),但在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>

试验
var keynum,行数=1;
功能限制线(obj,e){
//即
if(window.event){
keynum=e.keyCode;
//Netscape/Firefox/Opera
}否则,如果(例如,哪个){
keynum=e.which;
}
如果(keynum==13){
如果(行==对象行){
返回false;
}否则{
行++;
}
}
}
*编辑-解释:如果按下ENTER键,它会捕捉按键,如果textarea中的行与textarea中的行数相同,它不会添加新行。否则它会增加行数

编辑#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>

试验
.限制我{
高度:500px;
宽度:500px;
}
var线=1;
函数getKeyNum(e){
var-keynum;
//即
if(window.event){
keynum=e.keyCode;
//Netscape/Firefox/Opera
}否则,如果(例如,哪个){
keynum=e.which;
}
返回keynum;
}
var限制线=功能(e){
var-keynum=getKeyNum(e);
如果(keynum==13){
如果(行>=this.rows){
e、 停止传播();
e、 预防默认值();
}否则{
行++;
}
}
};
var setNumberOfLines=函数(e){
lines=getNumberOfLines(此.value);
};
var limitPaste=函数(e){
var剪贴簿数据,粘贴数据;
//停止将数据实际粘贴到div中
e、 停止传播();
e、 预防默认值();
//通过剪贴板API获取粘贴的数据
clipboardData=e.clipboardData | | window.clipboardData;
pastedData=clipboardData.getData('Text');
var pastedLines=getNumberOfLines(pastedData);
//用帕塞达做什么都行
如果(粘贴此.rows中的行){
//警告(“粘贴的行太多”);
this.value=pastedData
.split(/\r\n |\r |\n/)
.slice(0,此.rows)
.加入(“\n”);
}
};
函数getNumberOfLines(str){
如果(str){
返回str.split(/\r\n |\r |\n/).length;
}
返回1;
}
var limitedElements=document.getElementsByClassName('limit-me');
数组.from(limitedElements).forEach(函数(元素){
元素。addEventListener('keydown',限制线);
元素。addEventListener('keyup',setNumberOfLines);
元素。addEventListener('cut',setNumberOfLines);
元素。addEventListener('paste',limitPaste);
});

这与Ivan使用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>

$(函数()
{
函数getLines(id)
{
返回$('#'+id).val().split(“\n”).length
}
$(“#测试”).keyup(函数()
{
var allowedNumberOfLines=4;
if(getLines('testing')>allowedNumberOfLines)
{
modifiedText=$(this.val().split(“\n”).slice(0,allowedNumberOfLines);
$(this.val(modifiedText.join(“\n”));
}
});
});

如何使用jQuery:

绑定到textarea的keyDown事件

function limitTextareaLine(e) {
    if(e.keyCode == 13 && $(this).val().split("\n").length >= $(this).attr('rows')) { 
        return false;
    }
}
(使用jquery完成)。它不是完美的,但很在乎包装。不仅取消挂起行的结尾(\n)
jquery scroll事件在mozilla和firefox中存在问题,如果textarea中的css溢出属性不是自动的,则删除相应的行并将溢出设置为隐藏。可以帮助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 */
});

我对它进行了一些扩展,以便在没有手动换行的情况下检测溢出。这适用于带有“溢出:隐藏”的固定大小文本区域

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

var-keynum,allowedLines=5,defaultFontSize=13/*px*/;
$(文档).ready(函数(){
$(“文本区域”).keydown(函数(e,obj){
if(window.event)
keynum=e.keyCode;
否则,如果(例如,哪个)
keynum=e.which;
如果(keynum==13&&allowedLines此解决方案有效:

<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>

函数limitTextarea(textarea、maxLines、maxChar){
var lines=textarea.value.replace(/\r/g').split('\n'),删除行,删除字符,i;
如果(maxLines&&lines.length>maxLines){
lines=lines.slice(0,maxLines);
删除的行数=1
}
if(maxChar){
i=直线长度;
而(i-->0)if(行[i].length>maxChar){
林
<asp:TextBox ID="myWishTB" runat="server" Height="185px" TextMode="MultiLine" 
             Style="overflow: auto;" Width="95%" 
             onkeyup="limitTextarea(this,10,80)">
</asp:TextBox>
<textarea id="textareaID" onkeyup="limitTextarea(this,5,100)" cols="20" rows="5">   </textarea>
  //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);
  });