专业编程基础技术教程

网站首页 > 基础教程 正文

实现一个高度自适应的输入框

ccvgpt 2024-08-04 12:10:37 基础教程 58 ℃

需求

  • 实现一个输入框,高度可以随着输入文字的增加而自动增高,类似于微信输入
  • 输入为空时,显示placeholder
  • 字数限制maxlength

方法1:使用textarea配合工具函数autosize实现高度自适应的输入框(支持IE9+),具体代码如下:

实现一个高度自适应的输入框

<!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及其他高级浏览器

希望本文能帮助到您!

点赞+转发,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓-_-)

关注 {我},享受文章首发体验!

每周重点攻克一个前端技术难点。更多精彩前端内容私信 我 回复“教程”

原文链接:http://eux.baidu.com/blog/fe/%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E9%AB%98%E5%BA%A6%E8%87%AA%E9%80%82%E5%BA%94%E7%9A%84%E8%BE%93%E5%85%A5%E6%A1%86

作者:李明

Tags:

最近发表
标签列表