textarea 多行文本
<textarea> 是 HTML 中用于输入多行纯文本的表单元素。与 <input type="text"> 只能输入单行文本不同,<textarea> 允许用户输入和编辑多行内容,适用于评论框、个人简介、文章编辑、地址输入等需要大量文本输入的场景。
前置知识
阅读本节前,建议先了解:image 图像按钮
基础概念
什么是 textarea
<textarea> 元素创建一个可编辑的多行文本区域。主要特点:
- 多行输入:支持换行和多段落文本
- 内容作为子节点:默认值写在开闭标签之间(而非
value属性) - 自动滚动:内容超出可见区域时自动出现滚动条
- 可调大小:用户可通过拖拽右下角调整尺寸(可通过 CSS 控制)
与 input type="text" 的对比
| 特性 | <input type="text"> | <textarea> |
|---|---|---|
| 行数 | 单行 | 多行 |
| 默认值 | value 属性 | 标签内容 |
| 换行 | 不支持 | 支持 |
| 滚动 | 不支持 | 支持 |
| 尺寸调整 | 不支持 | 支持拖拽调整 |
| 适用场景 | 短文本(姓名、标题) | 长文本(评论、文章) |
语法
基本用法
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>textarea 基本示例</title>
</head>
<body>
<h2>用户反馈</h2>
<form>
<label for="feedback">请输入您的反馈:</label>
<textarea id="feedback" name="feedback" rows="5" cols="40"></textarea>
<button type="submit">提交</button>
</form>
</body>
</html>设置默认值
<textarea> 的默认值写在标签之间,而非 value 属性:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>textarea 默认值</title>
</head>
<body>
<h2>编辑模板</h2>
<form>
<label for="template">邮件模板:</label>
<textarea id="template" name="template" rows="5" cols="50">尊敬的用户:
感谢您的关注。我们已收到您的请求,将尽快处理。
此致
敬礼</textarea>
<button type="submit">保存</button>
</form>
</body>
</html>rows 和 cols 属性
| 属性 | 说明 | 默认值 |
|---|---|---|
rows | 可见行数 | 2 |
cols | 可见列数(字符宽度) | 20 |
html
<!-- 大文本区域 -->
<textarea rows="10" cols="80" name="article">在此输入文章内容...</textarea>
<!-- 小文本区域 -->
<textarea rows="2" cols="30" name="note">备注...</textarea>详细说明
placeholder 占位文本
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>textarea placeholder</title>
</head>
<body>
<h2>占位文本</h2>
<form>
<label for="comment">发表评论:</label>
<textarea
id="comment"
name="comment"
rows="4"
cols="50"
placeholder="请输入您的评论(不少于 10 个字)..."
></textarea>
<button type="submit">发表</button>
</form>
</body>
</html>maxlength 限制字数
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>textarea 字数限制</title>
</head>
<body>
<h2>字数限制</h2>
<form>
<label for="bio">个人简介(最多 200 字):</label>
<textarea
id="bio"
name="bio"
rows="4"
cols="50"
maxlength="200"
placeholder="简单介绍一下自己..."
></textarea>
<p><span id="char-count">0</span> / 200 字</p>
</form>
<script>
const bio = document.getElementById('bio');
const charCount = document.getElementById('char-count');
bio.addEventListener('input', function () {
charCount.textContent = this.value.length;
if (this.value.length >= 200) {
charCount.style.color = 'red';
} else {
charCount.style.color = '';
}
});
</script>
</body>
</html>resize 控制
通过 CSS 的 resize 属性控制用户是否可以拖拽调整文本区域大小:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>textarea resize</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
textarea {
width: 100%;
padding: 8px;
border: 2px solid #ddd;
border-radius: 6px;
font-size: 14px;
box-sizing: border-box;
margin-bottom: 12px;
}
.resize-both { resize: both; }
.resize-vertical { resize: vertical; }
.resize-horizontal { resize: horizontal; }
.resize-none { resize: none; }
.resize-limited {
resize: vertical;
min-height: 80px;
max-height: 300px;
}
</style>
</head>
<body>
<h2>resize 控制</h2>
<label>自由调整(默认):</label>
<textarea class="resize-both" rows="3" placeholder="可自由拖拽调整"></textarea>
<label>仅垂直调整:</label>
<textarea class="resize-vertical" rows="3" placeholder="只能调整高度"></textarea>
<label>禁止调整:</label>
<textarea class="resize-none" rows="3" placeholder="不可调整大小"></textarea>
<label>限制高度范围:</label>
<textarea class="resize-limited" rows="3" placeholder="高度限制在 80px ~ 300px"></textarea>
<table border="1" cellpadding="8" style="margin-top: 16px;">
<tr><th>resize 值</th><th>效果</th></tr>
<tr><td><code>both</code>(默认)</td><td>可同时调整宽度和高度</td></tr>
<tr><td><code>vertical</code></td><td>只能调整高度</td></tr>
<tr><td><code>horizontal</code></td><td>只能调整宽度</td></tr>
<tr><td><code>none</code></td><td>禁止调整</td></tr>
</table>
</body>
</html>readonly 和 disabled
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>textarea readonly/disabled</title>
</head>
<body>
<h2>只读与禁用</h2>
<form>
<div>
<label for="readonly-text">只读内容:</label>
<textarea id="readonly-text" name="readonly_text" readonly rows="3"
cols="40">这段文字只能查看,不能修改,但会随表单提交。</textarea>
</div>
<div>
<label for="disabled-text">禁用内容:</label>
<textarea id="disabled-text" name="disabled_text" disabled rows="3"
cols="40">这段文字灰色显示,不能修改,也不会提交。</textarea>
</div>
<button type="submit">提交</button>
</form>
</body>
</html>JavaScript 操作 textarea
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>textarea JavaScript</title>
</head>
<body>
<h2>textarea 值操作</h2>
<form>
<label for="editor">文本编辑器:</label>
<textarea id="editor" name="content" rows="6" cols="50" placeholder="在此输入文本..."></textarea>
<div style="margin-top: 8px;">
<button type="button" id="count-btn">统计字数</button>
<button type="button" id="upper-btn">转大写</button>
<button type="button" id="clear-btn">清空</button>
</div>
<p id="stats"></p>
</form>
<script>
const editor = document.getElementById('editor');
const stats = document.getElementById('stats');
// 获取和设置值(与 input 相同使用 value 属性)
document.getElementById('count-btn').addEventListener('click', () => {
const text = editor.value;
const chars = text.length;
const charsNoSpace = text.replace(/\s/g, '').length;
const words = text.trim() ? text.trim().split(/\s+/).length : 0;
const lines = text ? text.split('\n').length : 0;
stats.textContent =
`字符数:${chars} | 不含空格:${charsNoSpace} | 词数:${words} | 行数:${lines}`;
});
document.getElementById('upper-btn').addEventListener('click', () => {
editor.value = editor.value.toUpperCase();
});
document.getElementById('clear-btn').addEventListener('click', () => {
editor.value = '';
stats.textContent = '';
editor.focus();
});
</script>
</body>
</html>selectionStart 和 selectionEnd
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>textarea 选区操作</title>
</head>
<body>
<h2>选区操作</h2>
<textarea id="editor" rows="5" cols="50" placeholder="选中文本后点击按钮...">HTML 表单是 Web 开发中最重要的交互元素之一。通过表单,用户可以向服务器提交数据。</textarea>
<div style="margin-top: 8px;">
<button type="button" id="wrap-btn">加粗选中文本</button>
<button type="button" id="select-all-btn">全选</button>
</div>
<script>
const editor = document.getElementById('editor');
document.getElementById('wrap-btn').addEventListener('click', () => {
const start = editor.selectionStart;
const end = editor.selectionEnd;
const text = editor.value;
const selected = text.substring(start, end);
if (selected) {
editor.value = text.substring(0, start) + '**' + selected + '**' + text.substring(end);
// 恢复选区
editor.selectionStart = start;
editor.selectionEnd = end + 4;
}
});
document.getElementById('select-all-btn').addEventListener('click', () => {
editor.focus();
editor.select();
});
</script>
</body>
</html>实战示例
带工具栏的简单编辑器
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>简易编辑器</title>
<style>
body { font-family: sans-serif; max-width: 700px; margin: 40px auto; }
.toolbar {
padding: 8px;
background: #f5f5f5;
border: 2px solid #ddd;
border-bottom: none;
border-radius: 6px 6px 0 0;
display: flex;
gap: 4px;
flex-wrap: wrap;
}
.toolbar button {
padding: 4px 12px;
border: 1px solid #ccc;
background: #fff;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.toolbar button:hover { background: #e0e0e0; }
textarea {
width: 100%;
padding: 12px;
border: 2px solid #ddd;
border-top: none;
border-radius: 0 0 6px 6px;
font-size: 15px;
line-height: 1.6;
box-sizing: border-box;
resize: vertical;
min-height: 250px;
}
textarea:focus { outline: none; border-color: #4a90d9; }
</style>
</head>
<body>
<h2>简易文本编辑器</h2>
<div class="editor">
<div class="toolbar">
<button type="button" onclick="format('bold')"><b>B</b> 加粗</button>
<button type="button" onclick="format('italic')"><i>I</i> 斜体</button>
<button type="button" onclick="format('link')">链接</button>
<button type="button" onclick="format('code')">代码</button>
<button type="button" onclick="format('list')">列表</button>
<button type="button" onclick="clearEditor()" style="margin-left: auto;">清空</button>
</div>
<textarea id="editor" name="content" placeholder="在此输入内容..."></textarea>
</div>
<script>
function format(type) {
const editor = document.getElementById('editor');
const start = editor.selectionStart;
const end = editor.selectionEnd;
const text = editor.value;
const selected = text.substring(start, end);
let replacement = '';
switch (type) {
case 'bold': replacement = `**${selected || '加粗文本'}**`; break;
case 'italic': replacement = `*${selected || '斜体文本'}*`; break;
case 'link': replacement = `[${selected || '链接文字'}](url)`; break;
case 'code': replacement = '`' + (selected || '代码') + '`'; break;
case 'list': replacement = `- ${selected || '列表项'}`; break;
}
editor.value = text.substring(0, start) + replacement + text.substring(end);
editor.focus();
}
function clearEditor() {
document.getElementById('editor').value = '';
}
</script>
</body>
</html>注意事项
默认值写法
<textarea> 不支持 value 属性设置默认值,必须写在标签之间:
html
<!-- 正确 -->
<textarea name="content">默认内容</textarea>
<!-- 错误:value 属性无效 -->
<textarea name="content" value="默认内容"></textarea>空格和换行保留
<textarea> 中的空格和换行会被保留。注意 HTML 源代码中的缩进也会成为内容的一部分:
html
<!-- 小心缩进带来的前导空格 -->
<textarea name="code">
function hello() {
console.log('hello');
}
</textarea>读取值使用 value 属性
虽然默认值写在标签之间,但 JavaScript 读取和设置值都通过 value 属性(与 <input> 一致):
javascript
const textarea = document.getElementById('my-textarea');
console.log(textarea.value); // 读取值
textarea.value = '新的内容'; // 设置值最佳实践
- 合理设置初始尺寸:使用
rows和cols设置合适的初始可见区域 - CSS 控制尺寸:优先使用 CSS
width和min-height而非 HTML 属性 - 配合 maxlength 和字数统计:提供实时字数反馈
- 控制 resize 行为:大多数场景建议
resize: vertical或resize: none - 提供 placeholder:当无默认值时,提供清晰的提示文本
- 注意 HTML 缩进:避免标签内容的缩进被作为默认值的一部分
下一节
继续学习:button 按钮元素