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


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 相关文章推荐
指定位置如果有图片显示图片,无图片显示广告的JS
Jun 05 Javascript
javascript instanceof 内部机制探析
Oct 15 Javascript
通过Jscript中@cc_on 语句识别IE浏览器及版本的代码
May 07 Javascript
JavaScript动态插入script的基本思路及实现函数
Nov 11 Javascript
正则表达式中特殊符号及正则表达式的几种方法总结(replace,test,search)
Nov 26 Javascript
Jquery时间轴特效(三种不同类型)
Nov 02 Javascript
jQuery限制图片大小的方法
May 25 Javascript
解析微信JS-SDK配置授权,实现分享接口
Dec 09 Javascript
js实现简单的手风琴效果
Feb 27 Javascript
vue实现消息的无缝滚动效果的示例代码
Dec 05 Javascript
使用react render props实现倒计时的示例代码
Dec 06 Javascript
详解ng-alain动态表单SF表单项设置必填和正则校验
Jun 11 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安全开发库中文详细介绍
2015/03/22 PHP
JS 页面自动加载函数(兼容多浏览器)
2009/05/18 Javascript
javascript function调用时的参数检测常用办法
2010/02/26 Javascript
input禁止键盘及中文输入,但可以点击
2014/02/13 Javascript
js的2种继承方式详解
2014/03/04 Javascript
教你使用javascript简单写一个页面模板引擎
2015/05/05 Javascript
推荐10 个很棒的 jQuery 特效代码
2015/10/04 Javascript
初步了解javascript面向对象
2015/11/09 Javascript
基于MVC4+EasyUI的Web开发框架形成之旅之界面控件的使用
2015/12/16 Javascript
jQuery Mobile操作HTML5的常用函数总结
2016/05/17 Javascript
浅谈Angular 中何时取消订阅
2017/11/22 Javascript
vue中post请求以a=a&amp;b=b 的格式写遇到的问题
2018/04/27 Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
2018/07/27 Javascript
nodejs实现用户登录路由功能
2019/05/22 NodeJs
js使用文件流下载csv文件的实现方法
2019/07/15 Javascript
layui 解决富文本框form表单提交为空的问题
2019/10/26 Javascript
uni-app微信小程序登录授权的实现
2020/05/22 Javascript
Vertx基于EventBus发送接受自定义对象
2020/11/16 Javascript
Python实现全角半角字符互转的方法
2016/11/28 Python
python自定义异常实例详解
2017/07/11 Python
Python内建函数之raw_input()与input()代码解析
2017/10/26 Python
Python之Scrapy爬虫框架安装及使用详解
2017/11/16 Python
Python实现的txt文件去重功能示例
2018/07/07 Python
浅谈Python中threading join和setDaemon用法及区别说明
2020/05/02 Python
Keras中的多分类损失函数用法categorical_crossentropy
2020/06/11 Python
python db类用法说明
2020/07/07 Python
CSS3为背景图设置遮罩并解决遮罩样式继承问题
2020/06/22 HTML / CSS
拉斯维加斯酒店、演出、旅游、俱乐部及更多:Vegas.com
2019/02/28 全球购物
StudentUniverse英国:学生航班、酒店和旅游
2019/08/25 全球购物
澳洲最大的时尚奢侈品电商平台:Cettire
2020/06/15 全球购物
在数据文件自动增长时,自动增长是否会阻塞对文件的更新
2014/05/01 面试题
房地产出纳岗位职责
2013/12/01 职场文书
高中生逃课检讨书
2014/10/10 职场文书
2015年幼儿园教育教学工作总结
2015/05/25 职场文书
Python数据可视化之绘制柱状图和条形图
2021/05/25 Python
python实现会员信息管理系统(List)
2022/03/18 Python