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


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 相关文章推荐
屏蔽Flash右键信息的js代码
Jan 17 Javascript
JS实现日期加减的方法
Nov 29 Javascript
json中换行符的处理方法示例介绍
Jun 10 Javascript
javascript中传统事件与现代事件
Jun 23 Javascript
JavaScript+CSS实现的可折叠二级菜单实例
Feb 29 Javascript
实现JavaScript的组成----BOM和DOM详解
May 18 Javascript
Vue响应式原理详解
Apr 18 Javascript
微信小程序 跳转传递数据的实例
Jul 06 Javascript
jQuery制作全屏宽度固定高度轮播图(实例讲解)
Jul 08 jQuery
JS装饰器函数用法总结
Apr 21 Javascript
微信小程序调用天气接口并且渲染在页面过程详解
Jun 24 Javascript
Electron vue的使用教程图文详解
Jul 05 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
收音机玩机评测 406 篇视频合集
2020/03/11 无线电
详解php语言最牛掰的Laravel框架
2017/11/20 PHP
thinkphp5修改view到根目录实例方法
2019/07/02 PHP
不错的asp中显示新闻的功能
2006/10/13 Javascript
JavaScript学习笔记之Function对象
2015/01/22 Javascript
jQuery Validate插件实现表单强大的验证功能
2015/12/18 Javascript
javascript url几种编码方式详解
2016/06/06 Javascript
如何解决手机浏览器页面点击不跳转浏览器双击放大网页
2016/07/01 Javascript
详解nodejs express下使用redis管理session
2017/04/24 NodeJs
使用express获取微信小程序二维码小记
2019/05/21 Javascript
基于VUE的v-charts的曲线显示功能
2019/10/01 Javascript
解决Vue打包上线之后部分CSS不生效的问题
2019/11/12 Javascript
linux 下以二进制的方式安装 nodejs
2020/02/12 NodeJs
Vue父子传递实例讲解
2020/02/14 Javascript
在Webpack中用url-loader处理图片和字体的问题
2020/04/28 Javascript
Vue页面手动刷新,实现导航栏激活项还原到初始状态
2020/08/06 Javascript
Node.js文本文件BOM头的去除方法
2020/11/22 Javascript
[02:04]2014DOTA2国际邀请赛 DK一个时代的落幕
2014/07/21 DOTA
[01:38]DOTA2第二届亚洲邀请赛中国区预选赛出线战队晋级之路
2017/01/17 DOTA
用smtplib和email封装python发送邮件模块类分享
2014/02/17 Python
python实现按行切分文本文件的方法
2016/04/18 Python
Django框架模板注入操作示例【变量传递到模板】
2018/12/19 Python
python快速排序的实现及运行时间比较
2019/11/22 Python
Pytorch 多块GPU的使用详解
2019/12/31 Python
python matplotlib imshow热图坐标替换/映射实例
2020/03/14 Python
美国围栏公司:Walpole Outdoors
2019/11/19 全球购物
学习心得体会
2014/01/01 职场文书
基督教婚礼主持词
2014/03/14 职场文书
2014年两会学习心得范例
2014/03/17 职场文书
精彩的演讲稿开头
2014/05/08 职场文书
文明工地标语
2014/06/16 职场文书
教师党员个人自我剖析材料
2014/09/29 职场文书
小学生作文评语集锦
2014/12/25 职场文书
恋恋笔记本观后感
2015/06/16 职场文书
人事任命书范本
2015/09/21 职场文书
解决hive中导入text文件遇到的坑
2021/04/07 Python