如何限制textarea>中的行数?

How do you restrict the number of rows in a <textarea>?

本文关键字:何限制 textarea      更新时间:2023-09-26

给定以下代码:

<textarea rows="4" cols="50"></textarea>

有4行要输入

但是,当用户按下回车键或当文本溢出到第五行时,如何应用CSS来禁用另一行呢?

使用JavaScript来限制行(行)。您需要通过input事件

完成此操作。

并且可以使用String.prototype.split()来分割数组中的行,之后可以使用Array.prototype.slice(start, end)来控制限制,即start必须具有0,这将是获得的第一行,而end是所需的最大行数。最后,将数组连接成一个字符串

看到的例子:

注意,我使用setTimeout是为了避免多次执行,以防用户中断地持有任何键。

function limitText(textarea, limit) {
    function limitLines() {
        // split lines
        var lines = textarea.value.split("'n");
        if (lines.length > limit) {
            textarea.value = lines.slice(0, limit).join("'n");
        }
    }
    // Limite on add event
    limitLines();
    var timeout;
    textarea.addEventListener("input", function () {
        clearTimeout(timeout);
        timeout = setTimeout(limitLines, 1);
    });
}
limitText(document.getElementById("txtField1"), 4);
limitText(document.getElementById("txtField2"), 4);
<textarea rows="4" cols="50" id="txtField1">1
2
3
4</textarea>
<textarea rows="4" cols="50" id="txtField2">a
b
c
d</textarea>

使用textarea

限制行和字符在一个文本区域,你可以使用我刚才做的脚本:

JAVASCRIPT:

function textarealimit(textarea, rows, chars, rowsleft_id, charsleft_id) {
    var newValue;
    var valueSegments = textarea.value.split(''n');
    if(rows != undefined && valueSegments.length > rows) { // too many rows
        newValue = valueSegments.slice(0, rows).join("'n");
    }
    if(chars != undefined && textarea.value.length > chars) { // too many chars
        if(newValue != undefined) 
            newValue = newValue.substring(0, chars);
        else
            newValue = textarea.value.substring(0, chars);
    }
    if(newValue != undefined) textarea.value = newValue;
    if(rowsleft_id != undefined) {
        if(textarea.value == "") document.getElementById(rowsleft_id).innerHTML = rows;
        else if(rows - valueSegments.length >= 0) document.getElementById(rowsleft_id).innerHTML = rows - valueSegments.length;
    }
    if(charsleft_id != undefined) {
        if(chars != undefined) document.getElementById(charsleft_id).innerHTML = chars - textarea.value.length;
    }
}
HTML:

<textarea onkeydown="textarealimit(this, 4, 43, 'textarea_rowsleft', 'textarea_charsleft');" 
onkeyup="textarealimit(this, 4, 43, 'textarea_rowsleft', 'textarea_charsleft');" 
onpaste="textarealimit(this, 4, 43, 'textarea_rowsleft', 'textarea_charsleft');" 
rows="4" style="overflow: hidden; resize: none;">
</textarea>
<div>
    Rows left: <span id="textarea_rowsleft">4</span>
    Characters left: <span id="textarea_charsleft">43</span>
</div>

如果你使用HTML5,你甚至可以通过文本区域控件上的maxlength属性来限制字符。如果不想显示剩下的行或字符,只需使用onkey....="textarealimit(this, 4, 43);"。您甚至可以通过使用onkey....="textarealimit(this, 4);"来限制行数。

这里有一个演示给你:http://jsfiddle.net/AmFnA/9/

唯一的限制出现在用户由于宽度限制而通过自动换行获得新行时,因此无需按ENTER键,因为它将不算作新行。此外,您必须始终使用keydown(当用户按下并按住它时一直触发),keyup(当用户释放时,即使按下ENTER也会触发)和onpaste(用于右键单击->粘贴)。

感谢Guilherme用他的简短版本提醒我粘贴部分。


使用多个输入字段

现在还有Jukka提到的另一种选择。您可以为每一行使用一个输入字段。这将防止用户自动获得换行。在这里,您甚至可以监听键,以便在适当的条件下将光标发送到下一个或上一个框。

在HTML中使用输入字段构建行:

<div class="rowfield_collection">
    <input id="rowfield1" class="rowfield top" onkeydown="rowfieldkeynav(event, undefined, 'rowfield2');" type="text" size="35" maxlength="30" />
    <input id="rowfield2" class="rowfield middle" onkeydown="rowfieldkeynav(event, 'rowfield1', 'rowfield3');" type="text" size="35" maxlength="30" />
    <input id="rowfield3" class="rowfield middle" onkeydown="rowfieldkeynav(event, 'rowfield2', 'rowfield4');" type="text" size="35" maxlength="30" />
    <input id="rowfield4" class="rowfield bottom" onkeydown="rowfieldkeynav(event, 'rowfield3', undefined);" type="text" size="35" maxlength="30" />
</div>

如您所见,每个输入字段都有自己的ID,您可以在rowfieldkeynav调用中引用前一个和下一个输入字段。

要使它看起来像一个文本区域,你可以使用以下CSS:

.rowfield {
    margin: 0 0 -1px 0;
    display: block;
}
.rowfield.top {
    border-bottom: 0;
}
.rowfield.middle {
    border-top: 0;
    border-bottom: 0;
}
.rowfield.bottom {
    border-top: 0;
}

最后是JAVASCRIPT函数:

function rowfieldkeynav(e, before_id, after_id) {
    var evtobj = window.event ? event : e //distinguish between IE's explicit event object (window.event) and Firefox's implicit.
    var unicode = evtobj.charCode ? evtobj.charCode : evtobj.keyCode;
    if(before_id != undefined && e.currentTarget.value.length == 0 && unicode == 08) { // BACKSPACE
        document.getElementById(before_id).focus();
    }
    else if(after_id != undefined && unicode == 13 || e.currentTarget.value.length >= e.currentTarget.maxLength) { // ENTER or end of row reached
        document.getElementById(after_id).focus();
    }
}

当当前输入字段为空并且按BACKSPACE时,它将跳转到上一个输入字段。当您按ENTER键或达到maxlength长度时,它将跳转到下一个输入字段。

这里有一个演示:http://jsfiddle.net/6KVMS/2/

这个方法仅有的几个缺点是:

  • 它会跳到单词中间的新行,所以它不会把当前单词带进新的输入字段。
  • 使用鼠标时不能选择多行。
  • 点击
  • 可以跳转到下一行
  • 如果你在另一行的上方删除一行,文本将不会向上移动
  • IE8和可能更低的哭声一点:它不会跳到下一个字段时,行是完整的

你可以在CSS中这样做:

textarea {
    overflow:hidden;
    resize:none;
}

这将关闭调整文本区域大小的可能性,并隐藏除指定的行数之外的所有内容。

此外,您可能希望通过maxlength (Spec)限制文本区域的字符数量,这是可能的,因为HTML5

不能在CSS中设置这样的限制。您可以在HTML中设置最大字符数,但这不是一回事。你可以使用JavaScript计算行数并施加限制。

通常,最好的方法似乎是避免这个问题:使用四个input元素而不是一个textarea元素。缺点是用户需要tab到下一个字段,而不是直接按Enter。

可以使用HTML maxlength属性,但HTML, CSS和JavaScript可以被黑客攻击。做一个服务器侧检查,以确保。客户端也应该使用,但不能防止潜在的问题。