如何将文本区域中每行的字符数限制为固定值

IT技术 javascript asp.net-mvc
2021-03-17 04:33:51

在我的文本区域中,我应该每行只能输入 72 个字符。如果我使用 cols 属性设置为 72,它会根据字符宽度允许更多或更少的字符数。

任何人都可以帮助如何做到这一点?

6个回答

Textarea重复每行限制字符 Jquery 或 Javascript

<TEXTAREA NAME="HARD" COLS="72" ROWS="5" WRAP="HARD">
这在 IE 或任何其他浏览器中根本不起作用,因为字体字符的宽度不同。一种选择是使用 width:50ch 尽管 IE 浏览器有问题。Javascript 是唯一可行的方法。
2021-05-04 04:33:51
@user2101274 试试看,如果您要强制使用列数,则可能应该使用单色字体来缓解问题
2021-05-09 04:33:51

我遇到了同样的问题,并试图用 JavaScript 解决它。为什么不直接采用 Juan Mendes 建议的 HTML 代码?

嗯,这很简单:它不能真正跨浏览器工作,或者至少在 Ubuntu 下的 Firefox 25 中,每行的最大字符数似乎受 textarea 宽度的限制,并且取决于我可以输入的字体大小 +-1信。但我希望每行的字符数限制为特定值,无论 textarea 的宽度是多少。所以我想出了这个代码:

var maxLength = 3;
$('#mytext').on('input focus keydown keyup', function() {
    var text = $(this).val();
    var lines = text.split(/(\r\n|\n|\r)/gm); 
    for (var i = 0; i < lines.length; i++) {
        if (lines[i].length > maxLength) {
            lines[i] = lines[i].substring(0, maxLength);
        }
    }
    $(this).val(lines.join(''));
});

我还准备了一个jsFiddle我希望这可以帮助别人 :)

最后只是对这段代码如何工作的简短解释:

  • 该函数等待以下事件之一:input、focus、keydown、keyup(使用这么多事件可能看起来有点不必要,但我进行了大量测试以找到这个组合,它可以跨浏览器工作并且总是触发,无论是否只有一个输入字母,连续按下该键或将文本粘贴到 textarea 中)
  • 它获取 textarea 的值
  • 然后它将每个换行符处的 textarea 拆分为一个新的数组元素
  • for 循环遍历这个数组并检查数组的每一行和元素,如果它超过了之前设置的 maxLength
  • 如果一行超过 maxLength,则该行在 maxLength 个字符后被“截断”
  • 最后,当没有剩下比 maxLength 个字符长的行时,数组元素再次连接到一个字符串中

编辑:我现在发现的唯一限制是,当在行首或行内输入附加字符时,代码会“切断”末尾的字符串,而不是添加字符的位置。这在大多数情况下无关紧要,但请记住:) 无论如何,适当更改此功能应该不会太困难,但在大多数情况下会浪费资源 ;)

3 年后,它现在应该可以在所有浏览器中正常工作
2021-04-25 04:33:51
@GuySchalnat 应该怎么做?Juan Mendes 的 html 解决方案还是在此答案中提出的解决方案?
2021-04-28 04:33:51
有没有办法不打破这个词?在这里帮助我stackoverflow.com/questions/68797727/...
2021-05-08 04:33:51

完成先前解决方案的一个小补充。
我也限制了行数。

它在旧系统中为我服务,其中 4 行注释保存在 4 个数据库条目中。

<textarea id="mytext" rows = "4" style="width:300px"></textarea>

$(function() {

    var maxLength = 30;
    var mawRow = 4;

    $('#mytext').on('input focus keydown keyup', function() {

        //get Textearea text
        var text = $(this).val();

        //Split with \n carriage return
        var lines = text.split("\n"); 

        for (var i = 0; i < lines.length; i++) {
            if (lines[i].length > maxLength) {
                lines[i] = lines[i].substring(0, maxLength);
            }     
        }

        //On supprime ce qui dépasse... :)
        while (lines.length > 4){    
            lines.pop();
        }

        //Join with \n.
        //Set textarea
        $(this).val(lines.join("\n"));
    });
});
有没有办法不打破这个词?在这里帮助我stackoverflow.com/questions/68797727/...
2021-05-08 04:33:51

这是一种在每行字符和行数中限制 textarea 的方法。为了让用户感觉输入交互更直观,它需要处理(1) 输入的值(2) 光标位置

  1. (a) 从 textarea 读取 VALUE,(b) 根据长度限制的要求检测每行文本是否太长,(c) 将溢出的文本从一行推送到下一行,以及 (d) 将 WRITE VALUE 写回 textarea .
  2. (a) 读取光标位置以存储光标位置,以及 (b) 将光标定位在用户在写入数据后预期的位置。

在此处查看代码笔:https ://codepen.io/MattWritingCode/pen/bmexwa

这是基本的 javascript 代码(在 Safari 和 Chrome 上测试,在将文本粘贴到 textarea 时也能正常工作):

var charactersPerLine=document.getElementById("charactersPerLine").value;
var maxLines=document.getElementById("maxLines").value;
var textOutput="";
var onPaste=false;

function formatTextAsRequired() {
  /*
  This function handles two aspects:
  1. (a) READ VALUE from the textarea, (b) DETECT IF TEXT PER LINE IS TOO LONG  as required by the length restrictions, (c) PUSH OVERFLOWING TEXT from a line to the next line and (d) WRITE VALUE back to the textarea.
  2. (a) READ THE CURSOR POSITION to store the cursor position, and (b) POSITION THE CURSOR where a user would expect it after WRITE DATA.
  */
  var textInput=document.getElementById("flexibleInputField").value;//1a: READ VALUE
  var inputAsRows=textInput.split("\n");// create array from input => each element contains one row of the textarea
  var inputAsOneLine=textInput.replace(/(\r\n\t|\n|\r\t)/gm,"");//remove all line-breaks
  var cursorPositionOnInput=document.getElementById("flexibleInputField").selectionStart;//2a: READ CURSOR POSITION
  var cursorOffsetAfterOutput=0;//set default value for cursor offset. cursor offset is needed when re-posiotioning the cursor after WRITE DATA

  var totalRows=inputAsRows.length; //don't put inputAsRows.length in the for statement, as the array is growing in the loop which results in an infinite loop
  var row;
  var lineBreakCount=0;
  var characterCount=0;
  for (row = 0; row < totalRows; ++row) {
    if(inputAsRows[row].length>charactersPerLine){ //1b DETECT IF TEXT PER LINE IS TOO LONG 
      if (inputAsRows[row+1] === undefined) {
        inputAsRows[row+1]="";// the row did not exist
        totalRows++;
        }
      //1c PUSH OVERFLOWING TEXT: move text that is too long for this row to the next row:
      inputAsRows[row+1]=inputAsRows[row].substring(charactersPerLine)+inputAsRows[row+1];
      inputAsRows[row]=inputAsRows[row].substring(0,charactersPerLine);
      //determine, if cursor was at the end of the line that got a line-break:
      var newOutput=inputAsRows.join("\n");
      if(newOutput.substr(cursorPositionOnInput-1,1)=="\n"){
        cursorOffsetAfterOutput=1; }
      }
    }

  if(inputAsRows.length<=maxLines && inputAsOneLine.length<=(maxLines*charactersPerLine)){//data is within max number of rows and max total digits
    textOutput=inputAsRows.join("\n");
    document.getElementById("flexibleInputField").rows=inputAsRows.length;//resize textarea
    document.getElementById("errors").innerHTML="";//remove error message
    document.getElementById("count").innerHTML=inputAsOneLine.length+"/"+(maxLines*charactersPerLine);//show digits count
    if(onPaste){ cursorOffsetAfterOutput=cursorOffsetOnPaste(textInput,cursorPositionOnInput,totalRows)
      }
    }
    else //data would be too long 
    {
    document.getElementById("errors").innerHTML="This field can only have "+maxLines+" lines with "+charactersPerLine+" characters per line.";//display error message
    document.getElementById("count").innerHTML="";//remove digits count
    cursorOffsetAfterOutput=-1;
  }
  document.getElementById("flexibleInputField").value=textOutput;//1d: WRITE VALUE
  document.getElementById("flexibleInputField").selectionStart=cursorPositionOnInput+cursorOffsetAfterOutput; //2b: POSITION CURSOR
  document.getElementById("flexibleInputField").selectionEnd=cursorPositionOnInput+cursorOffsetAfterOutput; //set a single cursor, not a selection
  onPaste=false;
}

function countLineBreaks(string,lengthFromStart){
  var left=string.substr(0,lengthFromStart);
  var countOfLinebreaks=(left.split("\n")).length;
  return countOfLinebreaks;
}

function handlePaste(){
  //some improvements when pasting content can still be made (particularly on the cursor position)
  onPaste=true;
}

function cursorOffsetOnPaste(textInput,cursorPositionOnInput,totalRows){
  //offset the cursor by 1 for each added line break:
  var countOld=countLineBreaks(textInput,cursorPositionOnInput);  
  var countNew=countLineBreaks(textOutput,cursorPositionOnInput+totalRows);
  cursorOffsetAfterOutput=countNew-countOld;
  return cursorOffsetAfterOutput;
}
抱歉,我不确定你在这里的意思。
2021-04-22 04:33:51
您好 感谢您的回复,它对我有用,但还有一个问题如何将它添加到画布并使用某些东西作为背景我在这样的项目中
2021-05-07 04:33:51
嗨,你能帮忙吗,我有一些同样的问题,你的代码工作得很好,但我想在下一行写完整的话,请回复
2021-05-16 04:33:51
2021-05-16 04:33:51
这是一个棘手的问题,因为我的代码实际上是围绕用一个 textarea 替换多个输入字段的想法设计的。但是,我能够创建一个版本,通过将每一行拆分为一个数组(单词是其元素)并通过它处理换行符来执行您正在寻找的内容。它有效,但我仍在寻找更优雅的解决方案。
2021-05-20 04:33:51

这是一个旧线程,但我刚刚开发了一个小的 jQuery 插件解决方案。检查它在这里查找自述文件以获取更多详细信息。我的插件有更多内容,但基本如下:

$(document).ready(function(){
        var linesUsed = $('#linesUsed');
        var charsUsed = $('#charsUsed');
        var errorreading = $('#errors');

        // HANDLES PASTE EVENTS
        $('.line_control').on('paste', function (e) {
            var $el = $(this);
            var lines = $el.attr("lines");
            var chars = $el.attr("chars");
            var errors = [];
            setTimeout(function (e) {
                var newLines = $el.val().split("\n");
                console.log(newLines);
                linesUsed.text(newLines.length);
                charsUsed.text(newLines[newLines.length - 1].length + 1);
                for (var i = 0, len = newLines.length; i < len; i++) {
                    if (newLines[i].length >= chars) {
                        let line = i + 1;
                        let count = newLines[i].length;
                        errors.push({
                            'line': line,
                            'count': count
                        })
                    }
                }
                if (errors.length > 0) {
                    var html = '<p>Errors:</p>';
                    var alertMessage = "Warning!\n\nYour pasted content has exceeded the line limitations. Please review the following:\n\n"
                    for (var i = 0, len = errors.length; i < len; i++) {
                        html = html + '<span>Line: ' + errors[i]['line'] + '</span></br><span>Count: ' + errors[i]['count'] + '</span></br>'
                        alertMessage = alertMessage + 'Line: ' + errors[i]['line'] + ' Over: ' + (errors[i]['count'] - chars) + ' Count: ' + errors[i]['count'] + '\n';
                    }
                    alert(alertMessage);
                    errorreading.html(html);
                }
                console.log(errors);
                if (newLines.length >= lines) {
                    linesUsed.css('color', 'red');
                    return false;
                } else {
                    linesUsed.css('color', '');
                }
                if (newLines[newLines.length - 1].length >= chars) {
                    charsUsed.css('color', 'red');
                    return false;
                } else {
                    charsUsed.css('color', '');
                }

            }, 100);
        });
        //HANDLES AND KEYDOWN EVENTS
        $('.line_control').keydown(function (e) {
            var lines = $(this).attr("lines");
            var chars = $(this).attr("chars");
            newLines = $(this).val().split("\n");
            linesUsed.text(newLines.length);
            charsUsed.text(newLines[newLines.length - 1].length + 1);
            if (newLines.length > lines && e.keyCode !== 8 && e.keyCode !== 46) {
                linesUsed.css('color', 'red');
                return false;
            } else if (e.keyCode !== 13 && e.keyCode !== 8 && e.keyCode !== 46 && newLines[newLines.length - 1].length >= chars) {
                charsUsed.css('color', 'red');
                return false;
            } else {
                linesUsed.css('color', '');
            }
        });
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<textarea class="line_control" lines="2" chars="8" style="resize: none;"></textarea>

有没有办法不打破这个词?在这里帮助我stackoverflow.com/questions/68797727/...
2021-04-24 04:33:51