文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

原生 CSS + JS 实现一个标签输入框

2024-12-02 04:15

关注

主要交互要求是这样的:

习惯了各种 react 框架或者UI库,大家有多久没接触没有原生开发了呢?有时候页面比较简单,没必要引入一个完整的框架,原生实现就完全满足了,一起看看吧!

一、自适应输入框布局

不管什么组件,布局都是最重要的。这个布局分为标签和输入框两个部分,假设 HTML 如下:


CSS

简单修饰一下:

.tags-content{
display: flex;
flex-wrap: wrap;
align-items: flex-start;
gap: 6px;
width: 400px;
box-sizing: border-box;
padding: 8px 12px;
border: 1px solid #D9D9D9;
border-radius: 4px;
font-size: 16px;
line-height: 24px;
color: #333;
outline-color: #4F46E5;
overflow: auto;
cursor: text;
}
tag{
display: flex;
align-items: center;
padding: 4px 0 4px 8px;
font-size: 16px;
line-height: 24px;
background: #F5F5F5;
color: rgba(0, 0, 0, 0.85);
cursor: default;
}
tag-close{
width: 18px;
height: 18px;
cursor: pointer;
background: url("data:image/svg+xml,%3Csvg width='10' height='10' viewBox='0 0 10 10' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.578 5l2.93-3.493a.089.089 0 0 0-.068-.146h-.891a.182.182 0 0 0-.137.064l-2.417 2.88-2.416-2.88a.178.178 0 0 0-.137-.064h-.89a.089.089 0 0 0-.069.146L4.413 5l-2.93 3.493a.089.089 0 0 0 .068.146h.89a.182.182 0 0 0 .138-.064l2.416-2.88 2.417 2.88c.033.04.083.064.137.064h.89a.089.089 0 0 0 .069-.146l-2.93-3.493z' fill='%23000' fill-opacity='.45'/%3E%3C/svg%3E") center no-repeat;
}
.tags-input{
flex: auto;
border: 0;
outline: 0;
padding: 4px 0;
line-height: 24px;
font-size: 16px;
}
.tags-content:focus-within,
.tags-content:active{
outline: auto #4F46E5;
}

注意几点实现技巧:

效果如下:

但是这里的输入框用 input 还是有些问题的,如下所示:

由于 input 输入内容无法跟随宽度自适应,所以有时候会出现文字被截断的情况:

理想情况下,当输入内容较多时,应该整体换行。如何实现呢?可以用普通的 div 来实现。


CSS

可以通过添加contenteditable或者以下 CSS 来实现:

.tags-input{
-webkit-user-modify: read-write-plaintext-only;
}

这个属性表示只允许输入纯文本,有兴趣的可以参考张鑫旭的这篇文章:小tip: 如何让contenteditable元素只能输入纯文本[1]。

这样可以自适应内容宽度了。

二、输入框占位提示

由于输入框已经从 input 换成了普通的 div 标签,并没有 placeholder 特性。不过,我们仍然可以通过其他 CSS 特性来实现占位效果,当输入框没有内容时,就可以匹配到 :empty选择器,然后通过伪元素::before动态生成 placeholder 内容,具体实现如下:

.tags-input:empty::before{
content: attr(placeholder);
color: #828282;
}

效果如下:

这样就几乎和 input 的占位效果一致了。

另外还有一种情况,如果需要仅在没有任何标签的情况下才显示占位,如何实现呢?可以想想,在没有任何标签的情况下,HTML 就变成了这样:



这种情况,就仅剩输入框唯一元素了,唯一元素可以通过:only-child来匹配,所以实现如下:

.tags-input:only-child:empty::before{
content: attr(placeholder);
color: #828282;
}

这样添加一个伪类就解决了。

两种需求都符合认知,看设计如何决定了。

三、标签的输入与删除

要实现标签的输入与删除就需要 JS 出马了,只需要监听键盘的“回车”和“退格”两个键值。需要注意的是,默认情况下,普通 contenteditable元素在回车时,会出现换行,如下:

因此,在监听键盘事件时需要阻止默认事件,然后动态创建标签元素,通过 before添加到输入框前面,具体实现如下:

// TagInput是输入框
TagInput.addEventListener('keydown', function(ev) {
if (ev.key === 'Enter') {
ev.preventDefault()
if (this.innerText) { // 输入框内容通过 innerText 获取
const tag = document.createElement('TAG');
tag.innerHTML = this.innerText + '';
this.before(tag);
this.innerText = '';
}
}
})

这样就能正常创建标签了。

然后是标签的删除。

这里有两种途径,首先看键盘的删除,具体逻辑是当输入框内容为空时删除标签,很简单,删除的标签就是输入框的前面一个元素,通过previousElementSibling获取,具体实现如下:

TagInput.addEventListener('keydown', function(ev) {
if (ev.key === 'Backspace' && !this.innerText) {
this.previousElementSibling?.remove(); // 需要判断前一个元素是否存在
}
})

然后是点击删除图标的删除。由于标签是动态生成的,所以这里需要用事件委托的方式来添加删除事件。

// TagContent是父级容器
TagContent.addEventListener('click', function(ev) {
if (ev.target.className === 'tag-close') {
ev.target.parentNode.remove();
}
TagInput.focus(); //点击任意地方输入框都需要聚焦
})

这样就实现了文章开头的所示效果:

完整代码可以访问:「文章底部原文链接」input-tag[2]。

四、选择框架还是原生?

总结一下!

整体实现并不算复杂,不少交互逻辑 CSS 也可以轻松实现,JS 也就 10 来行代码,这里总结一下实现要点:

在各种框架大行其道的氛围下,有些原生的属性和方法可能都不太关注了,这也不失为是一种损失。当然,我本身也是各种框架都会用,特别是大型、复杂的交互页面,一般比较小的交互,比如文章这个例子,在 ant design 中有相关的组件,也使用过,因为整体 UI 全是这种风格,设计也是按照这个设计的。后来需要单独开发一个 chrome 插件,也用到了这样一个交互,但是仅仅用了这样一个组件,引入整个框架就过于累赘了,所以还是选择直接原生实现,简单方便。

来源:前端侦探内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯