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


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 相关文章推荐
jquery1.4 教程二 ajax方法的改进
Feb 25 Javascript
javascript break指定标签打破多层循环示例
Jan 20 Javascript
总结Javascript中数组各种去重的方法
Oct 04 Javascript
关于javascript获取内联样式与嵌入式样式的实例
Jun 01 Javascript
vue多页面开发和打包正确处理方法
Apr 20 Javascript
JS闭包原理与应用经典示例
Dec 20 Javascript
JavaScript多种页面刷新方法小结
Apr 04 Javascript
小试小程序云开发(小结)
Jun 06 Javascript
基于Taro的微信小程序模板消息-获取formId功能模块封装实践
Jul 15 Javascript
vue基本使用--refs获取组件或元素的实例
Nov 07 Javascript
Javascript操作select控件代码实例
Feb 14 Javascript
js实现类选择器和name属性选择器的示例步骤
Feb 07 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
玩家交还《星际争霸》原始码光盘 暴雪报以厚礼
2017/05/05 星际争霸
php读取javascript设置的cookies的代码
2010/04/12 PHP
PHP类中Static方法效率测试代码
2010/10/17 PHP
php 数据库字段复用的基本原理与示例
2011/07/22 PHP
php笔记之:有规律大文件的读取与写入的分析
2013/04/26 PHP
ThinkPHP模板IF标签用法详解
2014/07/01 PHP
php常用数组函数实例小结
2016/12/29 PHP
PHP实现对文件锁进行加锁、解锁操作的方法
2017/07/04 PHP
IE7中javascript操作CheckBox的checked=true不打勾的解决方法
2009/12/07 Javascript
Uglifyjs(JS代码优化工具)入门 安装使用
2020/04/13 Javascript
使用js+jquery实现无限极联动
2013/05/23 Javascript
如何创建一个JavaScript弹出DIV窗口层的效果
2013/09/25 Javascript
本人自用的global.js库源码分享
2015/02/28 Javascript
jQuery使用hide方法隐藏元素自身用法实例
2015/03/30 Javascript
JS简单实现动画弹出层效果
2015/05/05 Javascript
使用jQuery中的wrap()函数操作HTML元素的教程
2016/05/24 Javascript
JavaScript编写一个简易购物车功能
2016/09/17 Javascript
详解Vue组件之间的数据通信实例
2017/06/17 Javascript
vue结合axios与后端进行ajax交互的方法
2018/07/06 Javascript
JavaScript实现异步图像上传功能
2018/07/12 Javascript
python实现代码行数统计示例分享
2014/02/10 Python
在Python中处理日期和时间的基本知识点整理汇总
2015/05/22 Python
python基于BeautifulSoup实现抓取网页指定内容的方法
2015/07/09 Python
Python实现类似jQuery使用中的链式调用的示例
2016/06/16 Python
Flask框架的学习指南之用户登录管理
2016/11/20 Python
python3.5+tesseract+adb实现西瓜视频或头脑王者辅助答题
2018/01/17 Python
python 获得任意路径下的文件及其根目录的方法
2019/02/16 Python
keras分类之二分类实例(Cat and dog)
2020/07/09 Python
HTML5中5个简单实用的API
2014/04/28 HTML / CSS
国外平面设计第一市场:99designs
2016/10/25 全球购物
冰淇淋店创业计划书范文
2013/12/27 职场文书
家长评语和期望
2014/02/10 职场文书
入党自我鉴定
2014/03/25 职场文书
祖国在我心中演讲稿400字
2014/05/04 职场文书
先进个人材料怎么写
2014/12/30 职场文书
MySQL优化之慢日志查询
2022/06/10 MySQL