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


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实现的仿Flash广告图片轮换效果
Apr 24 Javascript
JavaScript 在网页上单击鼠标的地方显示层及关闭层
Dec 30 Javascript
javascript利用apply和arguments复用方法
Nov 25 Javascript
JS调用页面表格导出excel示例代码
Mar 18 Javascript
使用canvas及js简单生成验证码方法
Apr 02 Javascript
vue组件实现弹出框点击显示隐藏效果
Oct 26 Javascript
Vue中的methods、watch、computed的区别
Nov 26 Javascript
微信小程序前端自定义分享的实现方法
Jun 13 Javascript
微信小程序实现一张或多张图片上传(云开发)
Sep 25 Javascript
vue制作抓娃娃机的示例代码
Apr 17 Javascript
基于jsbarcode 生成条形码并将生成的条码保存至本地+源码
Apr 27 Javascript
详解vue 组件注册
Nov 20 Vue.js
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类
2008/04/09 PHP
Wordpress php 分页代码
2009/10/21 PHP
Linux下CoreSeek及PHP扩展模块的安装
2012/09/23 PHP
PHP中的traits简单使用实例
2015/05/13 PHP
Smarty高级应用之缓存操作技巧分析
2016/05/14 PHP
php加密之discuz内容经典加密方式实例详解
2017/02/04 PHP
PHP5.0~5.6 各版本兼容性cURL文件上传功能实例分析
2018/05/11 PHP
如何解决PHP获取不到SESSION信息之一般情况
2019/10/10 PHP
php慢查询日志和错误日志使用详解
2021/02/27 PHP
jquery插件 cluetip 关键词注释
2010/01/12 Javascript
如何让页面加载完成后执行js
2013/06/26 Javascript
jQuery操作元素css样式的三种方法
2014/06/04 Javascript
JavaScript使用Max函数返回两个数字中较大数的方法
2015/04/06 Javascript
浅谈jQuery中replace()方法
2015/05/13 Javascript
微信小程序 页面跳转传递值几种方法详解
2017/01/12 Javascript
js实现旋转木马效果
2017/03/17 Javascript
vue2项目使用sass的示例代码
2017/06/28 Javascript
node实现socket链接与GPRS进行通信的方法
2019/05/20 Javascript
发布订阅模式在vue中的实际运用实例详解
2019/06/09 Javascript
零基础写python爬虫之爬虫框架Scrapy安装配置
2014/11/06 Python
Python3数据库操作包pymysql的操作方法
2018/07/16 Python
Python之使用adb shell命令启动应用的方法详解
2019/01/07 Python
使用Python轻松完成垃圾分类(基于图像识别)
2019/07/09 Python
python实现统计代码行数的小工具
2019/09/19 Python
pytorch模型预测结果与ndarray互转方式
2020/01/15 Python
python爬虫中url管理器去重操作实例
2020/11/30 Python
HTML5本地存储之Web Storage详解
2016/07/04 HTML / CSS
美国知名男士服饰品牌:Brooks Brothers(布克兄弟)
2016/08/25 全球购物
Omio波兰:全欧洲低价大巴、火车和航班搜索和比价
2018/02/16 全球购物
Chain Reaction Cycles俄罗斯:世界上最大的在线自行车商店
2019/08/27 全球购物
演讲稿格式范文
2014/05/19 职场文书
医德医风演讲稿
2014/05/20 职场文书
六五普法学习心得体会
2016/01/21 职场文书
《秦兵马俑》教学反思
2016/02/24 职场文书
如何使用Tkinter进行窗口的管理与设置
2021/06/30 Python
vue使用refs获取嵌套组件中的值过程
2022/03/31 Vue.js