我正在寻找一种方法来限制输入到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>
以上只是一个简单的例子,可以快速解释我想要的输出。解决方案应该通过表单文本字段绑定到输入。
想法?
干杯
答案 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>