输入框跟随文字内容适配宽实现示例


Posted in Javascript onAugust 14, 2022

实现源码

// 常见一个辅助元素
const fakeEle = document.createElement('div');
// 隐藏辅助元素
fakeEle.style.position = 'absolute';
fakeEle.style.left = '-9999px';
fakeEle.style.visibility = 'hidden';
fakeEle.style.whiteSpace = 'nowrap';
// 获取输入框元素的样式
const textboxEle = document.getElementById('textbox');
const styles = window.getComputedStyle(textboxEle);
// 将输入框的字体样式赋给辅助元素
fakeEle.style.font = styles.font;
// 将辅助元素添加到页面
document.body.appendChild(fakeEle);
const setWidth = function () {
    const string = textboxEle.value || textboxEle.getAttribute('placeholder') || '';
    fakeEle.innerHTML = string.replace(/\s/g, ` `);
    // 获取辅助元素的样式
    const fakeEleStyles = window.getComputedStyle(fakeEle);
    // 将辅助元素的宽度赋给输入框元素
    textboxEle.style.width = fakeEleStyles.width;
};
setWidth();
// 监听输入框元素内容变化,输入框宽度跟随文字内容数量适配
textboxEle.addEventListener('input', function (e) {
    setWidth();
});

大概思路

其实核心点就是,如何获取输入框元素内文字内容的宽度值?

直接通过输入框元素肯定是无法获取到其文字内容宽度的,我们需要跳出输入框的限制,将文字内容独立出来。

首先,我们肯定是能够拿到输入框的文字内容的,使用 input.value 即可获取文字内容。

OK,文字内容有了,如何计算文字内容的宽度呢?

文字内容宽度

实现方案其实有 2 种,一种是使用 Canvas 的能力,另一种是使用辅助的 div 元素。

可能大部分同学还不是很了解 Canvas,所以本文就使用 div 元素的方式进行讲解。

首先,先定义好最基础的 HTML 和 CSS,代码如下:

<input id="textbox" type="text" />
input {
  padding: 8px;
}

此时,我们会得到一个最基础的输入框元素,没有任何文字内容。当我们往输入框元素内输入内容时,输入框元素的宽度也不会跟随变化。

然后通过 JavaScript 创建一个辅助的 div 元素,我们先将它添加到 body 元素内。

需要注意的是,文字内容的宽度会各被字体样式、大小、行间距等等因素所影响。本文作为讲解,暂时不考虑这么多影响因素,但会通过影响因素之一 “字体” 相关做个相关示例,提供各位同学作为参考。

const fakeEle = document.createElement('div');
const textboxEle = document.getElementById('textbox');
// 获取输入框元素样式
const styles = window.getComputedStyle(textboxEle);
// 将输入框元素的 font 属性赋给辅助的 div 元素
fakeEle.style.font = styles.font;
document.body.appendChild(fakeEle);

监听输入框元素的 input 事件,将文字内容同步给 div 辅助元素。

然后再反向的,获取 div 辅助元素的宽度,赋值给输入框元素,这样是不是就实现了啦了?

const setWidth = function () {
  const string = textboxEle.value || '';
  fakeEle.innerHTML = string;
  // 获取辅助元素的样式
  const fakeEleStyles = window.getComputedStyle(fakeEle);
  // 将辅助元素的宽度赋给输入框元素
  textboxEle.style.width = fakeEleStyles.width;
};
textboxEle.addEventListener('input', function (e) {
  setWidth();
});

我们来看看效果。

输入框跟随文字内容适配宽实现示例

当我们在输入框元素内随便输入一个内容,会发现输入框就撑满了整个页面。

输入框跟随文字内容适配宽实现示例

这是因为 div 辅助元素是块级元素,宽度默认是 100% 所导致的。那如何要获取文字内容宽度的话,要将它设置为行内元素嘛?

答案是不需要的,只要给 div 辅助元素添加绝对定位,使其脱离正常文档流即可。

// ...
fakeEle.style.position = 'absolute';
// ...

输入框跟随文字内容适配宽实现示例

输入框跟随文字内容适配宽实现示例

此时,我们会发现已经基本实现了我们想要的效果。

是的,我们已经解决了最核心的问题,但仍然还存在一些问题,需要我们进行处理。

细节处理

比如,输入多个空格的时候,宽度计算就错误了。

输入框跟随文字内容适配宽实现示例

这就需要我们将空格进行一下处理,将它替换成 &nbsp 即可,代码如下:

// fakeEle.innerHTML = string;
fakeEle.innerHTML = string.replace(/\s/g, ` `);

还有,辅助元素不应该出现在界面上,所以我们要将他隐藏掉。

// ...
fakeEle.style.left = '-9999px';
fakeEle.style.visibility = 'hidden';
fakeEle.style.whiteSpace = 'nowrap';
// ...

还有一些其它小细节,有兴趣的话,自己尝试一下吧。

以上就是输入框跟随文字内容适配宽实现示例的详细内容,更多关于输入框文字内容宽度适配的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
DWR Ext 加载数据
Mar 22 Javascript
jquery实现可拖动DIV自定义保存到数据的实例
Nov 20 Javascript
javascript获取元素CSS样式代码示例
Nov 28 Javascript
第五篇Bootstrap 排版
Jun 21 Javascript
AngularJS的依赖注入实例分析(使用module和injector)
Jan 19 Javascript
JavaScript无缝滚动效果的实例代码
Mar 27 Javascript
Vue.js如何优雅的进行form validation
Apr 07 Javascript
jQuery实现下拉菜单动态添加数据点击滑出收起其他功能
Jun 14 jQuery
Angular 中使用 FineReport不显示报表直接打印预览
Aug 21 Javascript
JavaScript定时器常见用法实例分析
Nov 15 Javascript
浅谈vue.watch的触发条件是什么
Nov 07 Javascript
微信小程序对图片进行canvas压缩的方法示例详解
Nov 12 Javascript
JS开发前端团队展示控制器来为成员引流
Aug 14 #Javascript
JS实现页面炫酷的时钟特效示例
Rust中的Struct使用示例详解
Aug 14 #Javascript
使用Cargo工具高效创建Rust项目
Aug 14 #Javascript
JS实现刷新网页后之前浏览位置保持不变示例详解
Aug 14 #Javascript
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
Aug 05 #Vue.js
Vue深入理解插槽slot的使用
Aug 05 #Vue.js
You might like
PHP 时间日期操作实战
2011/08/26 PHP
php实现的简单数据库操作Model类
2016/11/16 PHP
php+Memcached实现简单留言板功能示例
2017/02/15 PHP
PHP CURL与java http使用方法详解
2018/01/26 PHP
Laravel框架学习笔记之批量更新数据功能
2019/05/30 PHP
Javascript 阻止javascript事件冒泡,获取控件ID值
2009/06/27 Javascript
JavaScript高级程序设计(第3版)学习笔记8 js函数(中)
2012/10/11 Javascript
JavaScript中this关键词的使用技巧、工作原理以及注意事项
2014/05/20 Javascript
Javascript中获取对象的原型对象的方法小结
2015/02/25 Javascript
HTML5之WebSocket入门3 -通信模型socket.io
2015/08/21 Javascript
javascript实现很浪漫的气泡冒出特效
2020/09/05 Javascript
深入剖析JavaScript:Object类型
2016/05/10 Javascript
Bootstrap学习笔记之css样式设计(1)
2016/06/07 Javascript
原生js实现无限循环轮播图效果
2017/01/20 Javascript
原生js实现网页顶部自动下拉/收缩广告效果
2017/01/20 Javascript
vue-router 前端路由之路由传值的方式详解
2019/04/30 Javascript
vue实现路由切换改变title功能
2019/05/28 Javascript
vue 中几种传值方法(3种)
2019/11/12 Javascript
Python中条件选择和循环语句使用方法介绍
2013/03/13 Python
Python的内存泄漏及gc模块的使用分析
2014/07/16 Python
深入理解Python中的元类(metaclass)
2015/02/14 Python
Django渲染Markdown文章目录的方法示例
2019/01/02 Python
Python Excel处理库openpyxl使用详解
2019/05/09 Python
python Django 创建应用过程图示详解
2019/07/29 Python
使用TensorFlow-Slim进行图像分类的实现
2019/12/31 Python
Python 使用双重循环打印图形菱形操作
2020/08/09 Python
艺术用品:Arteza
2018/11/25 全球购物
波兰购物网站:MALL.PL
2019/05/01 全球购物
自我鉴定书范文
2013/10/02 职场文书
民生工程实施方案
2014/03/22 职场文书
小学二年级数学教学计划
2015/01/20 职场文书
数学教师个人总结
2015/02/06 职场文书
2015年119消防宣传日活动总结
2015/03/24 职场文书
获奖感言范文
2015/07/31 职场文书
2016年5月份红领巾广播稿
2015/12/21 职场文书
Python 实现定积分与二重定积分的操作
2021/05/26 Python