有限行和字符限制的文本区域

4
我需要的功能是带有TextArea的文本框。
1) maximum total lines- 6 and 
2) in each line there must be maximum of 16 chars
3) if user enters 17th character the cursor should go to the next line 
and user will type in there (the line will be counted)
4) if user reaches to the 7th line it will not allow user to write
5) if user type e.g "Hello, I Love StackOverflow and its features" (counting 
from 1st Char 'H', the 16th char is 't' but it is whole word 'StackOverflow',
    it shouldn't break and continue to next line e.g.
        Hello, I Love St
        ackOverflow
now the whole word should come to next line like:

        Hello, I Love
        StackOverflow 
        and its features

这是我迄今为止完成的链接: http://jsfiddle.net/nqjQ2/2/ 有时一些功能会起作用,有时不会,并且在使用 onKeyUp 和 onKeyDown 时会遇到浏览器问题。谁能帮我解决这个问题?

2
强烈建议采用SO的做法:允许用户自由输入,显示他们是否超出限制,并在超出限制时不允许他们发布。但不要试图阻止他们超过限制。这是一种更好的用户体验。(在SO上在评论框中键入大量内容以了解我的意思。) - T.J. Crowder
从经验来看,在文本区域上编写此类逻辑是一项非常庞大且非常复杂的任务。您应该先退后一步,问问自己(或客户)是否真的值得为您/他们所做。 - jbabey
你将面临的最大问题是字体...并非所有字体都是等宽的(即无论使用哪个字符,它们的宽度都相同),这意味着您无法可靠地计算每行有多少个字符。除此之外,您还必须考虑浏览器自己的换行功能。您打算使用等宽字体吗? - Gavin
@gavin,我可以计算每行字符数,而且我正在使用字体族——Arial。 - SML
@gavin,我已经将文本区域的宽度调整为比实际大小宽16个字符,这样它就可以适应,并且浏览器不会自动换行。 - SML
显示剩余2条评论
2个回答

12

我认为这基本符合你的要求:

<textarea id="splitLines"></textarea>

JavaScript:

var textarea = document.getElementById("splitLines");
textarea.onkeyup = function() {
    var lines = textarea.value.split("\n");
    for (var i = 0; i < lines.length; i++) {
        if (lines[i].length <= 16) continue;
        var j = 0; space = 16;
        while (j++ <= 16) {
            if (lines[i].charAt(j) === " ") space = j;
        }
        lines[i + 1] = lines[i].substring(space + 1) + (lines[i + 1] || "");
        lines[i] = lines[i].substring(0, space);
    }
    textarea.value = lines.slice(0, 6).join("\n");
};

点击这里查看实际演示。


嗯... 显然它没有保留光标位置... 我得修复一下。 - Lukas
谢谢大家分享自己的意见,我真的很苦恼如何编写这些功能的代码。@Lukas,你的代码逻辑太惊人了,这是我见过的最棒的逻辑之一。我不知道在编写这么多功能时我们可以用如此简短的代码实现。 - SML
@Lukas已经为类似的问题苦苦挣扎了几天,看到了数十个建议,但仍然没有解决 - 真是太棒了!不过我想提出一些改进意见。例如,如果我输入"The quick brown fox...",然后回去添加"The VERY quick...",它会正确地重新排列单词,但不会在"brown"和"fox"之间添加空格。我认为我们可以这样做:lines[i + 1] = lines[i].substring(space + 1) + (lines[i + 1] ? " " + lines[i + 1] : "");,如果下一行已经有内容,就添加一个空格,可以在这里查看更新后的fiddle http://jsfiddle.net/9x5Fb/348/。 - Boris
@Lukas 如果我们按照上述方法在早期的一行中添加更多文本,导致下面的单词被重新排列,那么光标跳到文本的最末端的问题就出现了,因此您必须手动返回以继续在开始处输入。一旦另一个单词被带过来,光标再次跳动。有什么想法可以解决这个问题吗? - Boris
1
也解决了第二个问题 - http://jsfiddle.net/9x5Fb/350/,按照这里的建议将当前选择的起始和结束位置存储起来 https://dev59.com/rWUq5IYBdhLWcg3waP3r,并在应用文本框值后设置它们。只有在起始和结束位置相同时才这样做 - 这样仍然可以选择文本,否则每次按键都会重置选择。 - Boris
显示剩余3条评论

2
在Jquery中
$(function () {

    var limit = function (event) {
        var linha = $(this).attr("limit").split(",")[0];
        var coluna = $(this).attr("limit").split(",")[1];

        var array = $(this)
            .val()
            .split("\n");

        $.each(array, function (i, value) {
            array[i] = value.slice(0, linha);
        });

        if (array.length >= coluna) {
            array = array.slice(0, coluna);
        }

        $(this).val(array.join("\n"))

    }

    $("textarea[limit]")
        .keydown(limit)
        .keyup(limit);

})



<textarea limit='10,5'  cols=10 rows=5 ></textarea>

http://jsfiddle.net/PVv6c/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接