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


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中eval函数的使用方法与示例
Apr 09 Javascript
从sohu弄下来的flash中展示图片的代码
Apr 27 Javascript
Javascript new关键字的玄机 以及其它
Aug 25 Javascript
JQuery 1.6发布 性能提升,同时包含大量破坏性变更
May 10 Javascript
纯css+js写的一个简单的tab标签页带样式
Jan 28 Javascript
asp.net中oracle 存储过程(图文)
Aug 12 Javascript
概述如何实现一个简单的浏览器端js模块加载器
Dec 07 Javascript
自学实现angularjs依赖注入
Dec 20 Javascript
JS实现一次性弹窗的方法【刷新后不弹出】
Dec 26 Javascript
bootstrap PrintThis打印插件使用详解
Feb 20 Javascript
js实现瀑布流效果(自动生成新的内容)
Mar 16 Javascript
jQuery滚动插件scrollable.js用法分析
May 25 jQuery
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字符串处理的10个简单方法
2010/06/30 PHP
浅析ThinkPHP中execute和query方法的区别
2014/06/13 PHP
PHP实现Redis单据锁以及防止并发重复写入
2018/04/10 PHP
js操纵跨frame的三级联动select下拉选项实例介绍
2013/05/19 Javascript
jQuery下的动画处理总结
2013/10/10 Javascript
基于jquery扩展漂亮的CheckBox(自己编写)
2013/11/19 Javascript
jquery datepicker参数介绍和示例
2014/04/15 Javascript
jQuery移除tr无效的解决方法(tr是动态添加)
2014/09/22 Javascript
JavaScript使用addEventListener添加事件监听用法实例
2015/06/01 Javascript
JS使用parseInt解析数字实现求和的方法
2015/08/05 Javascript
jQuery插件实现无缝滚动特效
2015/11/24 Javascript
快速学习jQuery插件 Cookie插件使用方法
2015/12/01 Javascript
js实现截图保存图片功能的代码示例
2017/02/16 Javascript
JS实现多级菜单中当前菜单不随页面跳转样式而发生变化
2017/05/30 Javascript
利用jQuery实现简单的拖曳效果实例代码
2017/10/20 jQuery
基于vue-ssr服务端渲染入门详解
2018/01/08 Javascript
vue的安装及element组件的安装方法
2018/03/09 Javascript
trackingjs+websocket+百度人脸识别API实现人脸签到
2018/11/26 Javascript
JS实现二维数组元素的排列组合运算简单示例
2019/01/28 Javascript
vue 进阶之实现父子组件间的传值
2019/04/26 Javascript
Vue实现日历小插件
2019/06/26 Javascript
微信小程序用户授权、位置授权及获取微信绑定手机号
2019/07/18 Javascript
Vue实现开关按钮拖拽效果
2020/09/22 Javascript
[59:30]VG vs LGD 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.22
2019/09/05 DOTA
python链接oracle数据库以及数据库的增删改查实例
2018/01/30 Python
详谈python在windows中的文件路径问题
2018/04/28 Python
python文件操作之批量修改文件后缀名的方法
2018/08/10 Python
python简易实现任意位数的水仙花实例
2018/11/13 Python
PyQt5实现画布小程序
2020/05/30 Python
python脚本定时发送邮件
2020/12/22 Python
生物医学工程专业学生求职信范文分享
2013/12/14 职场文书
土木建筑学生自我评价
2014/01/14 职场文书
2014年文员工作总结
2014/11/18 职场文书
红色革命电影观后感
2015/06/18 职场文书
公司新员工欢迎词
2015/09/30 职场文书
使用python将HTML转换为PDF pdfkit包(wkhtmltopdf) 的使用方法
2022/04/21 Python