HTML5 textarea高度自适应的两种方案


Posted in HTML / CSS onApril 08, 2020

阅读全文你将获得以下解决方案。

  • 点击长文本编辑textarea,自动获得焦点
  • 随着输入值自动伸缩高度
  • 可复制添加信息
  • 可粘贴文本
  • 可粘贴图片

以下实例代码执行环境为Chrome80

方案一

HTML5 Textarea 元素

1. 自动获得焦点

点击编辑自动获得焦点后光标跳转到了最前面,why?

HTML5  textarea高度自适应的两种方案

查文档 MDN,textarea元素存在selectionEndselectionStart的属性用来表示选中的文本开始位置和结束位置,DOM接口实例是 HTMLTextAreaElement, 它具有 setSelectionRange 方法,用来选中输入框中的文本,用法:TextAreaElement.setSelectionRange(selectionStart, selectionEnd, [optional] selectionDirection);

那么我们只要做到selectionStart === selectionEnd === value.length , 这样光标就选中到最末尾。

edit.addEventListener("click", function() {
  txt.classList.add("hidden");
  document.body.insertBefore(textarea, edit);
  textarea.innerHTML = "这是需要编辑的信息";
  textarea.focus();
  // textarea.selectionEnd = textarea.innerHTML.length;

  textarea.setSelectionRange(
    textarea.innerHTML.length,
    textarea.innerHTML.length
  );
});

2. 自适应高度

当不设置高度时换行会出现滚动条,所以只要让textarea滚动条消失,让其height = scrollHieght, 那么如何监听textarea的变化,则需要input事件,让textarea高度动态等于它的scrollHeight即可,代码如下:

textarea.addEventListener("input", function() {
    this.style.height = `${this.scrollHeight}px`;
});

HTML5  textarea高度自适应的两种方案

为什么每次输入都会使得高度增加(每次增加4px),经过测试Safari同样也是这个效果,Firefox符合预期高度不异常增加,查看Chrome控制台发现textarea内置了很多样式,尝试将去掉padding后,可以正常随着内容增加高度自适应了。

<style>
textarea {
  padding: 0;
}
</style>
<textarea></textarea>
<script>
const textarea = document.createElement("textarea");
textarea.addEventListener("input", function(e) {
  this.style.height = `${this.scrollHeight}px`;
});
</script>

为什么去掉padding值,输入后高度就不增加了?(未找到合理的解释,欢迎留言讨论解答)

但是删除文本的情况下height并未能自动缩放,分析原因, 当删除文本换行的时候scrollHeight的大小并未发生改变,scrollHeight作为只读属性( MDN-文档),如何让scrollHeight高度重新计算哪?只有改变高度,于是:

textarea.addEventListener("input", function(e) {
  this.style.height = "inherit";
  this.style.height = `${this.scrollHeight}px`;
});

到此高度自适应输入内容完成,但是每次换行的闪动很难受,transition走一波,

textarea {
  overflow: hidden;  // 防止换行出现滚动条闪动
  padding: 5px 10px;
  box-sizing: border-box;
  transition: all 0.2s linear;
}

结果transition并没效果,原因height初始值或者参考值必须为数值过渡动画才会生效,height设置为auto或者inherit动画不会生效, 所以折中的办法就是当删除的时候重新重置高度,输入时不需要重置,这样输入时动画生效, 删除没有动画, 暂时没想到更好的办法。

textarea.addEventListener("keyup", function(e) {
  if (e.keyCode === 8) {
    this.style.height = "inherit";
    this.style.height = `${this.scrollHeight}px`;
  } else {
    this.style.height = `${this.scrollHeight}px`;
  }
});

3. 支持粘贴文本,图片等

textarea只能输入文本,无法实现粘贴图片。

textarea.addEventListener(
  "paste",
  function(e) {
    e.preventDefault();
    console.log(
      "paste",
      e.clipboardData.items,
      e.clipboardData.types,
      e.clipboardData.getData("text/html"),
      e.clipboardData.getData("text/plain"),
      e.clipboardData.getData("text/Files")
    );
  },
  false
);

方案二

div contenteditable 替换textarea

1. 自动获得焦点

编辑div contenteditabletrue,然后利用RangeSelection 光标移动到最后的效果。

edit.addEventListener("click", () => {
  textarea.setAttribute("contenteditable", true);
  textarea.focus();
  const range = document.createRange();

  // range 包含的内容
  range.selectNodeContents(textarea);

  // range.setStart(textarea.firstChild, 0);
  // range.setStart(textarea.lastChild, textarea.innerHTML.length);

  // 起始位置是否相同
  range.collapse(false);
  const sel = window.getSelection();
  
  // 将所有的区域都从选区中移除。
  sel.removeAllRanges();
  
  // 一个区域(Range)对象将被加入选区。
  sel.addRange(range);
});

2. 自适应高度

div contenteditable 天然支持根据输入来自适应高度。

3. 粘贴图片, 文本等

textarea.addEventListener("paste", function(e) {
  e.preventDefault();
  const clipboardData = e.clipboardData || e.originalEvent.clipboardData;
  // 获取纯文本
  let text = clipboardData.getData("text/plain");
  let file = clipboardData.getData("text/plain");
  // console.log(clipboardData.items, clipboardData.getData("text/Files"));

  // 插入img,可以做一些上传图片的一些操作
  insertImg(clipboardData);

  // 只输入纯文本
  document.execCommand("insertText", false, text);
});

此方法可以限定只能上传文本或者图片。

欢迎留言讨论其他textarea高度自适应的方案。

到此这篇关于HTML5  textarea高度自适应的两种方案的文章就介绍到这了,更多相关textarea高度自适应内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

HTML / CSS 相关文章推荐
CSS3动画之流彩文字效果+图片模糊效果+边框伸展效果实现代码合集
Aug 18 HTML / CSS
CSS3——齿轮转动关键代码
May 02 HTML / CSS
CSS3实现圆角、阴影、透明效果并兼容各大浏览器
Aug 08 HTML / CSS
CSS3实现点击放大的动画实例代码
Feb 27 HTML / CSS
CSS3 3D酷炫立方体变换动画的实现
Mar 26 HTML / CSS
Html5 Canvas 实现一个“刮刮乐”游戏
Sep 05 HTML / CSS
HTML5 Canvas中绘制椭圆的4种方法
Apr 24 HTML / CSS
HTML5中input[type='date']自定义样式与日历校验功能的实现代码
Jul 11 HTML / CSS
HTML5 input新增type属性color颜色拾取器的实例代码
Aug 27 HTML / CSS
详解h5页面在不同ios设备上的问题总结
Mar 01 HTML / CSS
CSS3常见动画的实现方式
Apr 14 HTML / CSS
HTML CSS 一个标签实现带动画的抖音LOGO
Apr 26 HTML / CSS
html5给汉字加拼音加进度条的实现代码
Apr 07 #HTML / CSS
详解HTML5如何使用可选样式表为网站或应用添加黑暗模式
Apr 07 #HTML / CSS
HTML5拖放API实现自动生成相框功能
Apr 07 #HTML / CSS
canvas绘制树形结构可视图形的实现
Apr 03 #HTML / CSS
Html5踩坑记之mandMobile使用小记
Apr 02 #HTML / CSS
总结html5自定义属性有哪些
Apr 01 #HTML / CSS
详解canvas.toDataURL()报错的解决方案全都在这了
Mar 31 #HTML / CSS
You might like
ThinkPHP中的常用查询语言汇总
2014/08/22 PHP
PHP实现微信小程序人脸识别刷脸登录功能
2018/05/24 PHP
asp函数split()对应php函数explode()
2019/02/27 PHP
[Web]防止用户复制页面内容和另存页面的方法
2009/02/06 Javascript
通过url查找a元素并点击
2014/04/09 Javascript
Jquery异步提交表单代码分享
2015/03/26 Javascript
JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍
2016/05/19 Javascript
js判断价格,必须为数字且不能为负数的实现方法
2016/10/07 Javascript
Bootstrap3 模态框使用实例
2017/02/22 Javascript
vue webuploader 文件上传组件开发
2017/09/23 Javascript
细说webpack源码之compile流程-rules参数处理技巧(2)
2017/12/26 Javascript
js阻止默认右键的下拉菜单方法
2018/01/02 Javascript
详解JavaScript基础知识(JSON、Function对象、原型、引用类型)
2018/01/16 Javascript
JS运动特效之完美运动框架实例分析
2018/01/24 Javascript
JS实现checkbox互斥(单选)功能示例
2019/05/04 Javascript
Vue 中获取当前时间并实时刷新的实现代码
2020/05/12 Javascript
python完成FizzBuzzWhizz问题(拉勾网面试题)示例
2014/05/05 Python
Pycharm学习教程(2) 代码风格
2017/05/02 Python
CentOS 6.5下安装Python 3.5.2(与Python2并存)
2017/06/05 Python
使用Pytorch来拟合函数方式
2020/01/14 Python
解决Tensorflow占用GPU显存问题
2020/02/03 Python
Python Opencv 通过轨迹(跟踪)栏实现更改整张图像的背景颜色
2020/03/09 Python
pip install 使用国内镜像的方法示例
2020/04/03 Python
关于python3.7安装matplotlib始终无法成功的问题的解决
2020/07/28 Python
基于Python实现天天酷跑功能
2021/01/06 Python
Lookfantastic葡萄牙官方网站:欧洲第一大化妆品零售商
2018/03/17 全球购物
介绍一下linux的文件权限
2012/02/15 面试题
常用UNIX 命令(Linux的常用命令)
2015/12/26 面试题
高中毕业生自我鉴定例文
2013/12/29 职场文书
大学生自助营养快餐店创业计划书
2014/01/13 职场文书
银行办公室岗位职责
2014/03/10 职场文书
企业元宵节主持词
2014/03/25 职场文书
《学会合作》教学反思
2014/04/12 职场文书
关于应聘教师的自荐信
2016/01/28 职场文书
Python趣味挑战之用pygame实现简单的金币旋转效果
2021/05/31 Python
Redis 持久化 RDB 与 AOF的执行过程
2021/11/07 Redis