自适应textarea文本域高度原理
自适应文本域高度原理。什么是自适应文本域高度?可能名字叫的不是很容易理解,这里解释下,就是一个文本域输入框的高度会跟随内容高度变化而刚好就是文本高度。这就是自适应文本域高度
文本域的标签通常就是 textarea,我们在页面上写个textarea,然后看看textarea会是什么样。
我们发现,textarea有自带的边框还有其他的样式等,我们先去除掉他默认的样式。
.textarea{outline: none;resize: none;border: none;padding: 0;overflow: hidden;
}
要实现文本自适应高度其实很简单,vant组件库,element组件库里面都有实现。但是这篇文章主要讲他的实现过程。
第一步:监听输入事件,当输入后将文本框的高度=scrollHeight
既然要拿到scrollHeight和监听事件就得获取他的dom。相对于ref获取dom,小编更喜欢通过自定义指令来获取dom并监听事件,于是就有如下代码。
<template><textarea v-input class="text-input" v-model="textValue"></textarea>
</template>
<script>
export default {data() {return {textValue: ""}},directives: {input: {// 指令的定义inserted: function(el, binding, vnode) {console.dir(el)el.addEventListener("input", function(e) {e.target.style.height = e.target.scrollHeight + "px"})}}}
}
</script>
<style scoped>
.text-input{width: 100%;outline: none;resize: none;/* border: none; */padding: 0;overflow: hidden;
}
</style>
但是以上这样会存在各种问题的。最终方案就是设计一个参考文本,用来判断高度。
主要问题有:
1、删除文本时,高度未重新计算
2、字体不一样,导致内容多时文本高度并不一样问题
3、删除文本到没内容时,高度为0 不可继续输入
4、点击回车换行,高度未能更新
以下代码即解决了以上问题
<template><div class="syx-auto-textarea" v-syx-input><div class="transparent-text" :style="style">{{textValue}}</div><textarea class="text-input" :style="style" v-model="textValue"></textarea></div>
</template><script>
export default {name: "SyxAutoTextarea",props: {color: {type: String,default: "#333"},fontSize: {type: String,default: "16px"},lineHeight: {type: String,default: "20px"},fontWeight: {type: String,default: "400"},wordBreak: {type: String,default: "break-all"},whiteSpace: {type: String,default: "pre-wrap"},fontFamily: {type: String,default: "monospace"},value: {type: String,default: ""}},directives: {syxInput: {// 指令的定义inserted: function(el, binding, vnode) {const lineHeight = +vnode.context.$props.lineHeight.split("px")[0]console.dir(el)if (el.children && el.children.length > 0) {const targetDom = el.children[1] //可输入文本domconst heightDom = el.children[0] //参考文本domtargetDom.style.height = heightDom.scrollHeight + "px"//解决父元素高度未能和文本框高度完全一致问题el.style.height = heightDom.scrollHeight + "px"targetDom.addEventListener("input", function(e) {setTimeout(() => {//解决点击回车换行时高度未跟新问题const lastWordIsEnter = e.target.value[e.target.value.length - 1] === "\n"let height = lastWordIsEnter ? heightDom.scrollHeight + lineHeight : heightDom.scrollHeight//解决内容为空时高度为0 导致输入框无法再次输入问题height = height === 0 ? lineHeight : heighte.target.style.height = height + "px"el.style.height = height + "px"}, 10)})}}}},data() {return {textValue: ""}},watch: {textValue(val) {this.$emit("input", val)}},computed: {style() {return `height: ${this.lineHeight};color: ${this.color};font-size: ${this.fontSize};line-height: ${this.lineHeight};font-weight: ${this.fontWeight};word-break: ${this.wordBreak};white-space: ${this.whiteSpace};font-family: ${this.fontFamily};`}},created() {this.textValue = this.value}
}
</script><style scoped>
.syx-auto-textarea {width: 100%;/* border: 1px solid #eee; */position: relative;
}
.syx-auto-textarea .transparent-text{width: 100%;height: auto !important;position: absolute;top: 0;left: 0;z-index: -1;font-family: monospace;opacity: 0;
}
.syx-auto-textarea .text-input{width: 100%;outline: none;resize: none;border: none;padding: 0;overflow: hidden;
}
</style>
使用方式如下
<template>
<el-form ref="form" :model="form" label-width="120px"><el-form-item label="2021新春祝福"><syx-auto-textarea v-model="form.text"></syx-auto-textarea></el-form-item>
</el-form>
</template><script>
export default {data() {return {form: {text: "二零二一,新年快乐,牛年大吉,身体健康,工作顺利,财源广进,家庭幸福"}}}
}
</script><style lang="scss" scoped>
/deep/ .el-form-item__content{border: 1px solid red;padding: 6px;
}
</style>
展示效果如下,粗略试了下,与element和vant的展示效果几乎完全一致。
搞这么多好像忘记讲原理了,原理就是:一个父div包含两个元素,一个是参考文本,一个是真正的输入框,参考文本框是会根据文本内容高度自适应高度的,输入框高度只要跟随这个高度即可,然后设置这个参考文本空为绝对定位,就会脱离文本流,不占用位置,再使他不可见且层级放到后面去就不会影响点击输入框。然后需要将参考文本和输入框文本的 字体大小,行高,字体,反正就是影响字体相关的参数全部设置成一致。这就是其原理。
使用参考文本这个技巧在前端中是一个很好的思路方法,曾今就遇到一个修改密码解码,需要将输入的文本变成*展示在文本框,这时就可以用一个真正的输入框透明掉,盖住底下展示的*号框。看到的是*号,但是操作的是顶部透明的部分,涉及知识点就是使用等宽字体,加上一系列样式操作,懂ps图层的就比较好理解。有的人可能就说直接用过滤器不就解决了?但是vmodel的输入框好像用不了过滤器吧!!!
。仅代表个人经验,如有更好的解决方式,请告知,谢谢,学一波。或者以上代码有bug我更改一波。
自适应textarea文本域高度原理相关推荐
- html textarea文本域高度自适应
1.可直接在 菜鸟教程网站测试页面中测试 <!DOCTYPE html> <html> <head><meta charset="utf-8&quo ...
- html textarea a 整体,html textarea文本域高度自适应
1.可直接在 菜鸟教程网站测试页面中测试 菜鸟教程(runoob.com) id="symptomTxt" οninput="autoTextAreaHeight(thi ...
- div模拟textarea文本域轻松实现高度自适应——张鑫旭
by zhangxinxu from http://www.zhangxinxu.com 本文地址: http://www.zhangxinxu.com/wordpress/?p=1362 一.关于t ...
- ElementUI-textarea文本域高度自适应设置的方法
一.概述 textarea默认情况下,当超出范围后,会在右边显示滑动条 体验不太好,不需要滑动条,根据内容,自动增加高度,并显示完整内容. 二.解决方法 主要有3种方式: :rows="2& ...
- php设置文本框高度,怎样让textarea文本域宽度和高度width及height自动适应
这次给大家带来怎样让textarea文本域宽度和高度width及height自动适应,让textarea文本域宽度和高度width及height自动适应的注意事项有哪些,下面就是实战案例,一起来看一下 ...
- 关于模拟文本域iview textarea文本域:autosize=quot;{minRows: 3,maxRows: 7}quot;这个属性的好处
具体写法:<Input v-model="value" type="textarea" :autosize="{minRows: 3,maxRo ...
- 限制Textarea文本域内容的长度
通过charCodeAt()函数获取字符的Unicode值,根据Unicode值得范围判断字符串中是否包含中文符,包含temp+2,不包含temp+1: 在body标签的onload加载事件中调用Ja ...
- 表单标签——input表单元素、select下拉表单元素和textarea文本域
表单标签 表单的目的是为了收集用户信息.在网页中,我们也要跟用户进行交互,收集用户资料,此时就需要表单. 表单的组成:在HTML中,一个完整的表单通常由表单域.表单控件(也称为表单元素)和提示信息三部 ...
- 限制textarea文本域中输入字符个数(防粘贴)
通常我们需要对用户文本输入进行字符数量上的限制,对于<input type="text" value="" />文本输入域,我们可以通过maxlen ...
最新文章
- 斜率小于0的连线数量 51Nod - 1107 (树状数组+离散化)
- 题解 【NOIP2016】组合数问题
- python利器怎么用-UliPad 初体验----python 开发利器
- codevs1217 借教室 题解
- 新型机器人模拟蜻蜓飞行可以乱真!
- 真相了!算法工程师的一天
- 【JDK源码】java.util.concurrent.atomic包常用类详解
- 【Linux_Fedora_系统管理系列】_1_用户登录和系统初始配置
- Java程序员应该了解的10个设计原则
- 10张图,让你瞬间给自己减压
- Gartner2017年BI研究计划曝光,来看看他研究的都是啥?
- CVE-2021-3156:隐藏10年之久的 Sudo 漏洞,可使任意用户获得root 权限(详述)
- apache mod_autoindex 详解
- 参加工作第三个月的感悟
- list排序成员函数对string对象与char*对象排序的差别
- linux安装及配置c++的opencv库
- 网络通信数据传输原理
- sql2005数据库置疑修复断电崩溃索引损坏
- MySQL-JDBC
- 虚幻4 游戏引擎(一):材质教学