将输入限制为textarea而没有不必要的约束

时间:2015-10-01 15:51:36

标签: javascript jquery html css

我正在寻找一种方法来限制输入到textarea的方式,使用户输入能够保持在指定区域内,不会对最大字符数做出不必要的约束。

显而易见的方法是maxlength,但这意味着maxlength将取决于所有大写字母输入占用多少空间,并且需要一个不必要的最大长度。

还有各种JS / jQuery解决方案限制了在文本区域中输入的行数(例如Limit number of lines in textarea and Display line count using jQuery),但据我所知,这些解决方案依赖于输入键,但如果将一段文本复制粘贴到文本区域,则无效。

澄清

<!doctype html>
<head>
    <style>
    .one{
        height: 60px;
        width: 55px;
        background-color: pink;
        font-size: 16px;
    }
    </style>    
</head>
<body>
    <div class="one">i i i i i i i i i i i i i i i i i i</div>
    <br>
    <div class="one">M M M M M M M M M</div>
</body>
</html>
Div one可以包含18个小写“i”但只有9个大写“M”,所以为了确保输入永远不会超过div 1,maxlength必须设置为9.一般的结果就是Div一个区域通常不会被充分利用。

以上只是一个简单的例子,可以快速解释我想要的输出。解决方案应该通过表单文本字段绑定到输入。

想法?

干杯

2 个答案:

答案 0 :(得分:2)

我看不出这是一个容易解决的问题。可能有人比我有更多的专业知识,但我能立即想到的唯一方法是创建一个字符映射并为它们分配宽度。使用此地图,您可以将任何新输入与地图进行比较,并确定输入的长度/宽度。

伪代码示例,这可能不会按原样运行;

   // YOUR CHAR MAP WITH WIDTHS ASSIGNED TO LETTERS
    var charMap = {
      i: 1,
      M: 2
    }

   // MAX AMOUNT OF CHARACTERS
   var charLimit = 18;

   // ASSUME THE TEXTAREA IS EMPTY, COULD GET ACTUAL WIDTH HERE INSTEAD
   var currentChars = 0;

   $('textarea').on('change', function{
     // GET ALL NEW INPUT
     var chars = $(this).val();
     // FOR LIMITING THE INPUT, THIS IS THE FINAL STRING THAT WILL END UP IN THE TEXTBOX
     var limitedUserInput = '';

     // CHECK EACH CHAR ONE BY ONE, COMPARING ITS WIDTH USING THE MAP
     for(var x = 0; x < chars.length; x++){
       currentChars += chars[x];
       // IF SIZE LIMIT NOT HIT, ADD CHARACTER TO OUTPUT STRING
       if(currentChars < charLimit){
         limitedUserInput += chars[x];
       }
     }

     // DISPLAY THE OUTPUT IN THE TEXT AREA (TRIMMING ANY EXTRA CONTENT)
     $(this).html = limitedUserInput;
   })

这将允许你有18 x charMap.i(18)或9 x charMap.M(18)。

我希望这有点道理。

答案 1 :(得分:0)

这是我对解决问题的出价。有一些错误,但我对此非常满意。

我花了很多时间通过计算文本区域中的行来尝试解决问题,但是当我遇到越来越复杂的解决方案时,我放弃了努力。

此解决方案取决于div高度并修剪从textarea用户输入生成的.substring,以使其适合所需的div,在本例中为myDiv。 trimed字符串也被放入第二个textarea,这将是表单中使用的文本区域。

<!doctype html>
<head>
    <script src="https://code.jquery.com/jquery-1.10.2.js"></script>

   <style>
    .myDiv{
        min-height: 100px;
        width: 100px;
        background-color: pink;
        position: absolute;
    }
    #mySecondDiv{
        background-color: transparent;
        border: 1px solid black;
    };
    </style>

</head>
<body>

<textarea id='userInput' cols="30" rows="7"></textarea>
<textarea id="toBeStored"></textarea>

<div class='myDiv'></div>
<div class='myDiv'></div>
<div class='myDiv' id='mySecondDiv'></div>

<script>
//For live versions set the 'left' property for .myDiv(0) and #toBeStored to negative so they are off screen
$('.myDiv').eq(0).offset({ top: 200, left: 350 });
$('#toBeStored').offset({ top: 10, left: 350});

$('.myDiv').eq(1).offset({ top: 200, left: 10 });
$('.myDiv').eq(2).offset({ top: 200, left: 10 });

var currentMaxChars = 0;
var testString = "";
var myDivHeight = $('.myDiv').height()

$(document).ready(function(){
    while($('.myDiv').eq(0).height() <= myDivHeight ){
        testString += " i";
        $('.myDiv').eq(0).html(testString);
        currentMaxChars++;
    };
    currentMaxChars = currentMaxChars*2;
    maxChars = currentMaxChars;

    $("#userInput").on('change keyup paste', function() {
        var input = $(this).val().replace(/\n/g, '<br/>');
        $('.myDiv').eq(1).html(input);

        var str = $('#userInput').val().replace(/\n/g, '<br/>');
        if(str.length == currentMaxChars){
            currentMaxChars = maxChars;
        };

        if($('.myDiv').eq(0).height() <= myDivHeight){
            $('.myDiv').eq(0).html(str.substring(0, currentMaxChars));
            $('#toBeStored').html(str.substring(0, currentMaxChars));
        } else {
            while($('.myDiv').eq(0).height() > myDivHeight){
                currentMaxChars--;
                $('.myDiv').eq(0).html(str.substring(0, currentMaxChars));
                $('#toBeStored').html(str.substring(0, currentMaxChars));
            };
        };
    });
});
</script>
</body>
</html>