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


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 相关文章推荐
JavaScript中变量提升 Hoisting
Jul 03 Javascript
js转义字符介绍
Nov 05 Javascript
纯js写的分页表格数据为json串
Feb 18 Javascript
js强制把网址设为默认首页
Sep 29 Javascript
Three.js学习之文字形状及自定义形状
Aug 01 Javascript
jQuery实现的简单在线计算器功能
May 11 jQuery
node.js操作mysql简单实例
May 25 Javascript
解决vue 中 echart 在子组件中只显示一次的问题
Aug 07 Javascript
使用vue-router与v-if实现tab切换遇到的问题及解决方法
Sep 07 Javascript
浅谈vue.use()方法从源码到使用
May 12 Javascript
JavaScript实现旋转木马轮播图
Mar 16 Javascript
原生js实现俄罗斯方块
Oct 20 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常用字符串的总结(待续)
2013/06/07 PHP
PHP中类与对象功能、用法实例解读
2020/03/27 PHP
用javascript实现的激活输入框后隐藏初始内容
2007/06/29 Javascript
jQuery textarea的长度进行验证
2009/05/06 Javascript
通过继承IHttpHandle实现JS插件的组织与管理
2010/07/13 Javascript
基于jQuery实现左右div自适应高度完全相同的代码
2012/08/09 Javascript
javascript框架设计读书笔记之字符串的扩展和修复
2014/12/02 Javascript
基于Jquery制作图片文字排版预览效果附源码下载
2015/11/18 Javascript
AngularJs动态加载模块和依赖注入详解
2016/01/11 Javascript
jQuery 翻页组件yunm.pager.js实现div局部刷新的思路
2016/08/11 Javascript
JS添加或修改控件的样式(Class)实现方法
2016/10/15 Javascript
Vue数据监听方法watch的使用
2018/03/28 Javascript
原生JavaScript实现remove()和recover()功能示例
2018/07/24 Javascript
js实现转动骰子模型
2019/10/24 Javascript
JS实现页面数据懒加载
2020/02/13 Javascript
[04:39]显微镜下的DOTA2第十三期—Pis卡尔个人秀
2014/04/04 DOTA
Python实现查找系统盘中需要找的字符
2015/07/14 Python
python xml解析实例详解
2016/11/14 Python
Python实现变量数值交换及判断数组是否含有某个元素的方法
2017/09/18 Python
Python cookbook(数据结构与算法)找到最大或最小的N个元素实现方法示例
2018/02/13 Python
tensorflow实现逻辑回归模型
2018/09/08 Python
python 与服务器的共享文件夹交互方法
2018/12/27 Python
Django+Xadmin构建项目的方法步骤
2019/03/06 Python
Python实现SMTP邮件发送
2020/06/16 Python
OpenCV 之按位运算举例解析
2020/06/19 Python
用python监控服务器的cpu,磁盘空间,内存,超过邮件报警
2021/01/29 Python
美特斯邦威官方商城:邦购网
2016/10/13 全球购物
英国可持续奢侈品包包品牌:Elvis & Kresse
2018/08/05 全球购物
eHarmony英国:全球领先的认真恋爱约会平台之一
2020/11/16 全球购物
使用索引(Index)有哪些需要考虑的因素
2016/10/19 面试题
PyQt QMainWindow的使用示例
2021/03/24 Python
结构工程个人自荐信范文
2013/11/30 职场文书
企业厂务公开实施方案
2014/03/26 职场文书
期末学生评语大全
2014/04/24 职场文书
受资助学生感谢信
2015/01/21 职场文书
一篇文章告诉你如何实现Vue前端分页和后端分页
2022/02/18 Vue.js