HTML textarea:多行输入、长度限制、readonly 与提交值

HTML textarea 接受多行纯文本。在其起始和结束标签之间放置初始内容,使用 rows/cols 设置显示大小,使用 minlength/maxlength 设置输入长度。设置 name 以通过表单提交值。

显示大小、初始内容和输入限制

textarea 需要一个闭合标签。与 input 不同,它不使用 HTML 的 value 属性来设置初始值。标签之间的换行和空格会影响内容,因此请检查格式缩进是否引入了不必要的输入。

属性 角色和限制
rows, cols 使用正整数设置可见行数和以平均字符宽度为单位的宽度。它们不会限制输入行数或字符数;CSS 的宽度和高度也会影响显示。
placeholder 当值为空时显示的提示。它不会作为实际值提交,并且在输入时消失,因此不会替代单独的标签。
required 在为空时阻止普通表单提交。它不会决定仅含空白的文本是否有意义。
minlength, maxlength 限制用户输入值的最小和最大长度,以 UTF-16 代码单元为单位。一个表情符号可能使用两个或更多单元。仅设置最小值允许为空;与 required 结合使用可强制输入。
readonly 阻止用户编辑,但允许聚焦和复制。指定名称时,它仍会包含在表单数据中。
disabled 禁用控件,并将其从表单数据和约束验证中排除。

运行一个完整的多行输入示例

将此完整代码保存为 textarea.html 并在浏览器中打开。无需服务器或额外库。提交按钮会显示浏览器的名称/值条目,而不是发送它们。

<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>textarea 输入与提交值</title>
  <style>
    body { font-family: sans-serif; margin: 24px; }
    label, textarea { display: block; }
    textarea { max-width: 100%; box-sizing: border-box; margin: 8px 0 20px; resize: vertical; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>填写咨询内容</h1>
  <form id="demo">
    <label for="message">内容(5~200个代码单元)</label>
    <textarea id="message" name="message" rows="4" cols="32"
      minlength="5" maxlength="200" required
      placeholder="请描述问题情况和期望结果。">这是第一行。
这是第二行。</textarea>
    <label for="reference">只读提示</label>
    <textarea id="reference" name="reference" rows="2" readonly>请同时填写订单编号。</textarea>
    <label for="locked">禁用字段</label>
    <textarea id="locked" name="locked" rows="2" disabled>此值不包含在提交数据中。</textarea>
    <button type="submit">查看提交值</button>
    <button type="reset">重置</button>
  </form>
  <pre id="result" aria-live="polite"></pre>
  <script>
    const form = document.querySelector('#demo');
    const result = document.querySelector('#result');
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      result.textContent = JSON.stringify([...new FormData(form).entries()], null, 2);
    });
    form.addEventListener('reset', () => { result.textContent = ''; });
  </script>
</body>
</html>
  1. 提交初始表单:message 和 reference 出现。JSON \n 表示值中有换行符;locked 被省略。
  2. 清除消息并提交:必填验证阻止它。然后直接输入两个或三个普通字符并提交,以检查最小长度验证。
  3. 输入 <b>Practice</b> 作为消息并提交。由于输入和输出都是文本,结果显示标签形状的文本而不是加粗文本。
  4. 重置会恢复原来的两行消息并清除结果。重置会返回 HTML 默认值,而不是将值置为空。

原生浏览器验证有助于用户输入和普通表单提交。对于脚本分配的值,这些检查不能保证,因此实际应用必须在服务器端验证必填值、允许的长度和格式。

区分视觉换行与实际换行

输入框宽度造成的视觉换行,与用户按 Enter 插入的实际换行不同。默认的 wrap="soft" 并不会仅因为文本在视觉上换行而添加提交的换行。wrap="hard" 会根据指定的列宽添加提交的换行,并且需要 cols。为了适应窄屏,从默认换行和 CSS 宽度开始。

示例中的 max-width: 100% 可以帮助在窄屏上保持字段在其父容器内,而 resize: vertical 允许用户更改其高度。cols="32" 的像素宽度取决于字体、字符宽度和浏览器,因此不要假设一行正好能容纳 32 个字符。

在 JavaScript 中读取值并在服务器上进行验证

通过 textarea.value 读取当前输入,通过 textarea.defaultValue 读取默认值。要读取用户编辑,请使用 value 而不是标签的 textContent。示例将结果写入 textContent,因此输入不会作为 HTML 执行。

readonly 和 disabled 不是安全控制。用户可以通过开发者工具或单独的请求修改值,因此应根据受信任的服务器数据验证不可更改的订单号或权限数据。如果服务器计算字节或其他字符单位,请检查其限制是否使用与浏览器 maxlength 相同的度量。

MDN 的 textarea 元素参考 解释了属性和约束。