需求
- 实现一个输入框,高度可以随着输入文字的增加而自动增高,类似于微信输入
- 输入为空时,显示placeholder
- 字数限制maxlength
autosize实现高度自适应的输入框(支持IE9+),具体代码如下:
方法1:使用textarea配合工具函数<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
textarea {
resize: none;
}
</style>
</head>
<script type="text/javascript" src="js/autosize.min.js"></script>
<body>
<textarea id="textarea" rows="1" placeholder="请输入内容..." maxlength="50"></textarea>
</body>
<script type="text/javascript">
autosize(document.querySelector('#textarea'));
</script>
</html>
注:因为textarea的默认高度为rows=2,所以需要将textarea的rows设置为1
方法2:div加属性contenteditable=true
我们知道可以将div的contenteditable设置伪true,将其变为可输入状态。代码如下:
<div contenteditable="true"></div>
这样就满足了我们的第一个需求——高度自适应。但是在手机上测试会发现第一个问题,iOS上面无法输入。经过查找资料,发现只需要为其添加如下样式即可:
div{
user-select:text;
-webkit-user-select:text;
}
实现placeholder
使用css+js实现 placeholder,思路:根据输入通过动态添加class,模拟placeHolder的行为,代码如下:
// css
.textarea {
width: 400px;
min-height: 20px;
max-height: 300px;
_height: 120px;
margin-left: auto;
margin-right: auto;
padding: 3px;
outline: 0;
border: 1px solid #a0b3d6;
font-size: 12px;
line-height: 24px;
padding: 2px;
word-wrap: break-word;
overflow-x: hidden;
overflow-y: auto;
border-color: rgba(82, 168, 236, 0.8);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);
position: relative;
user-select: text;
-webkit-user-select: text;
}
.placeholder:before {
content: '请输入内容...';
line-height: 30px;
position: absolute;
left: 5px;
top: 0;
z-index: 1;
}
// html
<div class="textarea placeholder" contenteditable="true" data-placeholder="请输入内容..." data-length="10"><br /></div>
// js
var oInputBox = document.querySelector('.textarea');
oInputBox.oninput = oInputBox.onpropertychange = function (ev) {
var innterStr = oInputBox.innerText;
var _this = this;
// placeholder
if (innterStr.length == 0) {
_this.classList.add('placeholder');
} else {
_this.classList.remove('placeholder');
}
};
到此,我们已经实现了第二个需求——可以设置placeholder
实现maxlength
同样的,我们也不能通过直接设置maxlength来满足需求。所以通过监听input事件来实时计算长度。
var oInputBox = document.querySelector('.textarea');
oInputBox.oninput = oInputBox.onpropertychange = function (ev) {
var innterStr = oInputBox.innerText;
var _this = this;
// maxlength
var len = parseInt(_this.getAttribute('data-length'));
if (innterStr.length > len) {
oInputBox.innerText = innterStr.substring(0,len);
}
};
以上代码看上去没有问题,但是会发现光标会跑到最前方,这样就会造成不好的用户体验,甚至出现Bug。所以在截取了最大长度的用户输入后,我们还需要将光标放到最后。完整JS代码如下:
var oInputBox = document.querySelector('.textarea');
oInputBox.oninput = oInputBox.onpropertychange = function (ev) {
var innterStr = oInputBox.innerText;
var _this = this;
// placeholder
if (innterStr.length == 0) {
_this.classList.add('placeholder');
} else {
_this.classList.remove('placeholder');
}
// maxlength
var len = parseInt(_this.getAttribute('data-length'));
if (innterStr.length > len) {
oInputBox.innerText = innterStr.substring(0,len);
}
// div innerText重新赋值之后的光标问题
if(navigator.userAgent.indexOf('MSIE') > -1) {
var range = document.selection.createRange();
_this.last = range;
range.moveToElementText(_this);
range.select();
document.selection.empty(); //取消选中
} else {
var range = document.createRange();
range.selectNodeContents(_this);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
};
到此为止,一个可以自动增加高度,并且支持placeholder和maxlength的输入框就完成了。
要点总结:
- 方法1:autosizejs方法通过监听textarea的input、keyup事件动态的获取其scrollHeight,计算出实际高度并配合overflow属性的改变来动态的改变 textarea的高度,此方法使用的时候需要注意的是textarea的rows属性要设置为1,两行以内的高度自适应就会出现问题;兼容性:IE9+
- 方法2:div设置contentEditable为true后,输入或删除内容时,其高度本身就会随着内容的变化而变化,我们需要解决的问题只是在输入过程中光标的位置问题;兼容性:IE11及其他高级浏览器