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


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 TO HTML 转换
Jun 26 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
Aug 12 Javascript
使用script的src实现跨域和类似ajax效果
Nov 10 Javascript
Grunt入门教程(自动任务运行器)
Aug 06 Javascript
Google 地图类型详解及示例代码
Aug 06 Javascript
vue项目中做编辑功能传递数据时遇到问题的解决方法
Dec 19 Javascript
基于jQuery插件jqzoom实现的图片放大镜效果示例
Jan 23 Javascript
详解angularjs获取元素以及angular.element()用法
Jul 25 Javascript
使用Vue完成一个简单的todolist的方法
Dec 01 Javascript
基于 Immutable.js 实现撤销重做功能的实例代码
Mar 01 Javascript
Cookbook组件形式:优化 Vue 组件的运行时性能
Nov 25 Javascript
解决三元运算符 报错“SyntaxError: can''t assign to conditional expression”
Feb 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
7个超级实用的PHP代码片段
2011/07/11 PHP
利用PHP如何实现Socket服务器
2015/09/23 PHP
php基于curl实现随机ip地址抓取内容的方法
2016/10/11 PHP
详解PHP swoole process的使用方法
2017/08/26 PHP
用于判断用户注册时,密码强度的JS代码
2009/01/01 Javascript
JS 类型转换常见方法小结
2010/05/31 Javascript
利用腾讯的ip地址库做ip物理地址定位
2010/07/24 Javascript
解决window.opener=null;window.close(),只支持IE6不支持IE7,IE8的问题
2014/01/14 Javascript
js function定义函数的几种不错方法
2014/02/27 Javascript
基于javascript实现listbox左右移动
2016/01/29 Javascript
使用Vue自定义指令实现Select组件
2018/05/24 Javascript
详解vue-cli3使用
2018/08/14 Javascript
vue解决弹出蒙层滑动穿透问题的方法
2018/09/22 Javascript
详解关于element el-button使用$attrs的一个注意要点
2018/11/09 Javascript
从0到1构建vueSSR项目之路由的构建
2019/03/07 Javascript
javascript中innerHTML 获取或替换html内容的实现代码
2020/03/17 Javascript
[08:53]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS 选手采访
2021/03/11 DOTA
Python and、or以及and-or语法总结
2015/04/14 Python
详解Python中用于计算指数的exp()方法
2015/05/14 Python
Python使用回溯法子集树模板解决迷宫问题示例
2017/09/01 Python
Python实现爬虫设置代理IP和伪装成浏览器的方法分享
2018/05/07 Python
python处理“
2019/06/10 Python
python2使用bs4爬取腾讯社招过程解析
2019/08/14 Python
python 调试冷知识(小结)
2019/11/11 Python
简单了解为什么python函数后有多个括号
2019/12/19 Python
Python如何使用turtle库绘制图形
2020/02/26 Python
为什么相对PHP黑python的更少
2020/06/21 Python
关于PySnooper 永远不要使用print进行调试的问题
2021/03/04 Python
CSS3之边框多颜色Border-color属性使用示例
2013/10/11 HTML / CSS
css3中transition属性详解
2014/09/02 HTML / CSS
Feelunique澳大利亚:欧洲的化妆品零售电商
2019/12/18 全球购物
体育教师自荐信范文
2013/12/16 职场文书
我未来的职业规划范文
2014/01/11 职场文书
大学组织委员竞选稿
2015/11/21 职场文书
公司团队口号霸气押韵
2015/12/24 职场文书
Python数据处理的三个实用技巧分享
2022/04/01 Python