最近有点空闲时间又在捣鼓一些东西,就比如说这次碰到的一个小问题是,在输入文本的时候一开始想到的是用 input
标签,但是这个标签只能支持一行,如果超出的情况下就会隐藏到后面看不见,这会导致不好使用体验。而且这次要做的也是多文本输入,抛弃 input
使用改成多文本可以换行的 textarea
实现,但是多文本也有自己的问题,虽说可以自己设置默认高度,然后超出会出滚动条,这样的就跟之前的一样也是隐藏出去的,那么需求有了,怎么去实现即不超出又能自动换行的 textarea
呢?
貌似,上面的需求很普遍,在以往的过程中都不会考虑这个问题,只要设置高一点的高度,加上设置 css
属性的 resize-y
使其纵向拉伸,这样就能解决一点问题,现在不去说这个我们可以换一个角度说怎么实现自适应高度的问题。
抛出这个问题,我想大部分人肯定想到会是用 js 实现一把梭哈 ? ,不说不行,但也是最不优雅的一种,且不说实现起来复杂多变,还要计算个文字的大小行高等等,麻烦的一比。所以这种方式忽略考虑。
第二个,可以用 h5 的属性 contenteditable="true"
来实现,此属性加入到 div
中可以让其可以编辑,差不多就相当于一个 textare
的使用,而且用起来方便操作简单,但问题是使用回车之后里面的文字内容做成div 包裹起来,使其获取内容元素不是很方便,所以可以考虑。
第三个,可以使用 css 的方式实现,思路其实也很简单,就是用一个 span
的高度去顶替 textarea
的高度,什么意思呢。打字也说不明白,看图就行了。
如上面的图所示,想象一下绿色的块是最大的盒子,然后里面包裹着两个盒子,一个黑色的
span
盒子和一个红色的 textarea
盒子,为什么会挤在一起,是因为我把红色的 textarea
的盒子设置成了绝对定位的布局方式 absolute
,而父元素的绿色盒子设置成相对定位 relative
,然后再把红色盒子的宽高都设置其父元素的 100%,也就是跟父元素一样的宽高大小了,最后我们再设置关键的 span
元素,为什么说是这个是关键,因为它需要的高度需要自己撑开给父元素,怎么撑开,那就要在 span
里面加入内容了,可以是 \n
的回车也可以是纯文字的内容,只要文字多起来 span
的高度就是撑高,顺带的父元素也会变高,那必须的红色盒子的 textarea
也会跟着父元素的 100% 变化!surprise, 是不是完美。
废话太多,还不如直接上代码演示;
html部分 ?
<div>
<span></span>
<textarea></textarea>
</div>
css部分 ?
div {
position: relative;
width: 100px;
border: 1px solid red;
}
span {
display: block;
min-height: 24px;
white-space: pre-wrap;
word-wrap: break-word;
visibility: hidden; /* 一定不要少了给它隐藏哦,留个站位 */
}
textarea {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
line-height: 24px;
resize: none;
outline: none;
border: none;
overflow: hidden;
margin: 0;
padding: 0;
}
JS 部分
const area = document.querySelector('textarea')
const text = document.querySelector('span')
area.addEventListener('input', function(event) {
text.innerHTML = event.target.value;
})
很简单的代码,试运行一下吧,怎么感觉有点和自己想的出路比较大的,回车的时候没有及时增高,会出现一闪的效果,仔细观察一下,当我不输入任何文字的时候直接回车,就会出现一小段的换行,按下第二次回车的时候才出现了正常的换行,这是为什么? 按 f12 对比一下 dom 数据的变化,可以发现,第一次的回车显然是没有效果的,因为 span 的内容里面是没有加入回车符的,直到第二次才有效果,在尝试加入一个文字就可以正常走流程了,但是最后一行回车的时候还是会有闪屏的问题出现,在中间回车就不会,思考是不是中间缺少神东西导致换行失效?实话说我没找到为什么的原因,但是尝试给后面加一个空格符之后,后面的闪动就消失了!!
修改一下 js 代码
text.innerHTML = event.target.value + ' ';
后面加入一个空的字符,就很流畅的回车了。但,凡是都还有但是,细心的朋友肯定又发现了,一直回车下去的话,文字就会向上偏移一点,这也是换行符导致的,既然每次添加的时候后面都加了空格符,那么在第一次的时候也要记得加上去才行哦。
再次修改一下 html 代码
<div>
<span> </span> // 加入一个空格符
<textarea></textarea>
</div>
这次改完之后,在运行全部的代码,完美自适应!接下来就只要获取文本的内容就可以了,也不需要用 JavaScript 计算什么行高了。很多问题都可以优先考虑使用 css 尝试一下是不是可这样解决,不要复杂化,记录一下。
最后在线看一下运行效果 地址 ,别忘记改一下里面的代码在运行哦。