博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
可自适应文本高度的输入框
阅读量:6482 次
发布时间:2019-06-23

本文共 2668 字,大约阅读时间需要 8 分钟。

可适应文本高度的输入框组件其实一开始是Ant design里面就有的,Element-ui也实现了,但是通过看源码,其实用的都是一个相似的js...

我们需要实现的这个组件,可以指定最小行数(minRows)和最大行数(maxRows),用来限定textarea的高度变化范围。

最终实现的效果

说一下具体的实现思路吧

  1. 在body中添加一个不可见的元素,样式尽可能的和组件输入框的一样。当输入框的值发生变化时,通过这个不可见的元素,去模拟计算这时候组件输入框文本所占高度height。
  2. 通过计算出单行高度,获得minRows * singleRowHeightmaxRows *singleRowHeight,这样就有了一个最大、最小高度范围。
  3. 最后,通过这三个值:height, minHeight, maxHeight.做一下范围判断,就可以获得组件输入框的实时高度了。

具体代码逻辑:

// 不可见的节点,用来模拟输入框,计算当前输入值所占的高度let hiddenTextarea;// 隐藏不可见节点,所使用的样式let HIDDEN_STYLE = `    // ...`;// 模拟输入框,需要考虑模拟哪些样式let NODE_STYLE = [    // ...];// 计算输入框的样式,padding, border, box-sizing, 以及模拟样式的值function calcNodeStyle(targetElement) {    var styles = window.getComputedStyle(targetElement);    // ...    return {nodeStyle,paddingSize,borderSize,boxSizing};}function calcTextareaHeight(targetElement, minRows=1, maxRows=null) {    // ...    // 增加不可见节点,模拟组件输入框的样式    hiddenTextarea.setAttribute('style', `${nodeStyle};${HIDDEN_STYLE}`);        // 计算出单行文本的高度    hiddenTextarea.value = '';    let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize;    // 计算当前输入值所占高度    hiddenTextarea.value = targetElement.value || targetElement.placeHolder;    let height = hiddenTextarea.scrollHeight;    // ...    let result = {};    if(minRows) {        // 根据单行文本高度,计算最小高度值    }    if(maxRows) {        // 根据单行文本高度,计算最大高度值    }        result.height = `${height}px`;    hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);    hiddenTextarea = null;    return result;}

scrollHeight

看一下MDN中对于scrollHeight的定义:

从下图中,我们可以很直观的看出,scrollHeight = 内容区域高度(content-height) + paddingSize。不包括border以及margin的值。

clipboard.png

在这个组件中,我们需要去模拟当前输入框的样式,去计算当前输入值会占多少的高度,就需要用到这个属性。

let HIDDEN_STYLE = `    height:0 !important;    overflow:hidden !important;    position: fixed !important;    top: -9999px !important;    left: -9999px !important;    opacity: 0 !important;`;function calcTextareaHeight(targetElement, minRows=1, maxRows=null) {    // ...    hiddenTextarea.value = '';    let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize;    hiddenTextarea.value = targetElement.value || targetElement.placeHolder;    let height = hiddenTextarea.scrollHeight;        if(boxSizing === 'border-box') {        height = height + borderSize;    } else if(boxSizing === 'content-box') {        height = height - paddingSize;    }}

注意HIDDEN_STYLE中,height: 0;这个非常重要。因为不这么做的话,你取到的scrollHeight的值是组件输入框的高度,而不是他输入值文本所占的高度。

还有一点需要提下,仔细看HIDDEN_STYLE的属性,我们都是通过visible, top, right, opacity来隐藏这个节点,而没有使用display:none; 因为,设置dispaly:none后,就没有这个节点了, scrollHeight是获取不到值的!!!

总结

只要明白了实现的思路,其实后面就好写了。关键点还是在于对于box-sizing,以及模拟样式的健壮性考虑。

通过这个组件:

  • 加深了对于scrollHeight的使用
  • 对于代码健壮性的理解,需要考虑多种情况(box-sizing)

转载地址:http://ybbuo.baihongyu.com/

你可能感兴趣的文章
php框架 写sql语句的,ThinkPHP3.2.3框架实现执行原生SQL语句的方法示例
查看>>
php xml文件中有 amp,PHP中使用DOMDocument来处理HTML、XML文档
查看>>
自制php解释器,如何编写可以修改PHP解释器内部的自定义PHP扩展?
查看>>
oracle 脚本定时,Oracle存储过程定时执行2种方法
查看>>
oracle 捕获 语句,oracle9i 怎样自动捕获DML 语句
查看>>
oracle存储%3e,oracle 11g 使用ASM存储迁移
查看>>
eclipse php快捷键,EclipsePHP Studio快捷键
查看>>
oracle查看分区索引是否可用,【Oracle】error code [1502]; ORA-01502;索引的分区处于不可用状态...
查看>>
php的魔术常量trait,PHP基础-函数和魔术常量
查看>>
linux进程间通知,linux 进程间通信之消息传递
查看>>
Linux内核哪个版本有网络,Linux内核4.4版本带来的网络新特性
查看>>
linux不待机命令,linux实现显示器不休眠
查看>>
linux内核TCP 源码分析,Linux内核源代码解析之TCP面向字节流
查看>>
linux 共享内存过大,64位Linux机器上最大可能的共享内存大小
查看>>
linux 大叶内存,hugepages大叶内存
查看>>
linux终端编程gcc,ubuntu 14.04 命令行方式gcc升级及版本切换
查看>>
android获取图片格式,android-如何获取从FileProvider类获取的图像文...
查看>>
android源码编译so文件,Android 源码中so库与对应源码路径
查看>>
android dialog指定位置,android--自己定义ProgressDialog显示位置(其他Dialog子类都能够设置)...
查看>>
android pull 间隔,GitHub - apicloudcom/UIPullRefresh: 下拉刷新模块源码(内含iOS和Android)...
查看>>