一般我是使用contenteditable
属性让一个<div>
接受文本输入,并通过JavaScript监听输入事件来更新内容或改变样式
contenteditable 是一个枚举属性,表示元素是否可被用户编辑。如果可以,浏览器会修改元素的组件以允许编辑;
该属性必须是下面的值之一:
true
或空字符串,表示元素是可编辑的。false
表示元素不是可编辑的。plaintext-only
表示元素的原始文本是可编辑的,但富文本格式会被禁用。
如果没有设置该属性的值(例如:<label contenteditable>Example Label</label>
),则其值被视为空字符串。
如果没给出该属性或设置了无效的属性值,则其默认值继承自父元素:即,如果父元素可编辑,该子元素也可编辑。
注意,虽然该属性允许设定的值包括 true
和 false
,但该属性仍是一个枚举属性而非布尔属性。
你可以使用 CSS caret-color 属性设置用于绘制文本插入 caret 的颜色。
完整代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Div模拟输入框示例</title>
<style>
.editable-div {
width: 300px;
min-height: 32px;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
margin: 10px 0;
outline: none;
white-space: pre-wrap; /* 保留换行 */
}
.editable-div:focus {
border-color: #409eff;
box-shadow: 0 0 4px rgba(64, 158, 255, 0.3);
}
.input-box {
width: 300px;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
margin: 10px 0;
}
.container {
max-width: 800px;
margin: 20px auto;
padding: 20px;
}
.output {
color: #666;
margin-top: 20px;
padding: 10px;
border: 1px dashed #ccc;
}
</style>
</head>
<body>
<div class="container">
<!-- 可编辑div -->
<div
class="editable-div"
contenteditable="true"
placeholder="请输入内容(支持换行)"
id="customInput"
></div>
<!-- 原生input -->
<input
type="text"
class="input-box"
placeholder="原生输入框"
id="nativeInput"
>
<!-- 输出区域 -->
<div class="output" id="output"></div>
<script>
const customInput = document.getElementById('customInput')
const nativeInput = document.getElementById('nativeInput')
const output = document.getElementById('output')
// 公共事件处理
const handleEvent = (type, element) => {
output.innerHTML = `
${new Date().toLocaleTimeString()}
<br>事件类型: ${type}
<br>当前值: ${element.innerText || element.value}
`
}
// 绑定div事件
customInput.addEventListener('input', () => handleEvent('input', customInput))
customInput.addEventListener('focus', () => handleEvent('focus', customInput))
customInput.addEventListener('blur', () => handleEvent('blur', customInput))
// 绑定input事件
nativeInput.addEventListener('input', () => handleEvent('input', nativeInput))
nativeInput.addEventListener('focus', () => handleEvent('focus', nativeInput))
nativeInput.addEventListener('blur', () => handleEvent('blur', nativeInput))
</script>
</div>
</body>
</html>
主要差异及使用场景说明:
-
核心差异:
-
div
使用contenteditable
属性实现可编辑,而input
是原生表单控件 -
div
可以包含富文本内容(文字样式、图片等),input
只能处理纯文本 -
div
没有value
属性,需要通过innerText/innerHTML
获取内容 -
input
支持原生表单验证和自动完成功能 -
div
的尺寸需要手动控制,input
有默认尺寸管理
-
事件支持:
-
常用事件(input/focus/blur/keydown等)两者都可以绑定
-
div
支持更丰富的文本操作事件(如粘贴HTML内容) -
input
支持特定表单事件(如invalid事件)
-
优势对比:
-
div优势:
-
支持多行文本和富文本
-
高度自定义样式和布局
-
可以嵌入其他HTML元素
-
更好的换行处理能力
-
-
input优势:
-
原生表单支持
-
更好的无障碍访问
-
移动端输入优化
-
自动完成和密码类型支持
-
-
使用场景举例:
-
使用
div
:-
富文本编辑器(如评论框带@用户功能)
-
需要自定义样式的标签输入框
-
代码编辑器(需要保留缩进和换行)
-
聊天输入框(需要插入表情)
-
-
使用
input
:-
登录表单
-
搜索框
-
需要自动填充的字段
-
需要原生表单验证的场景
-