精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

原生 CSS + JS 實現一個標簽輸入框

開發 前端
在各種框架大行其道的氛圍下,有些原生的屬性和方法可能都不太關注了,這也不失為是一種損失。

最近在項目中需要做一個標簽輸入框,還挺實用的,演示效果如下:

主要交互要求是這樣的:

  • 點擊輸入框可以輸入內容。
  • 按回車可以生成標簽。
  • 按退格鍵可以刪除標簽。
  • 點擊標簽上的關閉按鈕可以刪除標簽。

習慣了各種 react 框架或者UI庫,大家有多久沒接觸沒有原生開發了呢?有時候頁面比較簡單,沒必要引入一個完整的框架,原生實現就完全滿足了,一起看看吧!

一、自適應輸入框布局

不管什么組件,布局都是最重要的。這個布局分為標簽和輸入框兩個部分,假設 HTML 如下:

<div class="tags-content">
<tag>CSS<a class="tag-close"></a></tag>
<input class="tags-input" placeholder="添加標簽">
</div>

簡單修飾一下:

.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;
}

注意幾點實現技巧:

  • 標簽的間隔可以用 gap 實現。
  • 為了讓輸入框的區域鋪滿剩余空間,這里用到了flex: auto。
  • 為了讓父級處于聚焦狀態,這里用到了:focus-within。

效果如下:

但是這里的輸入框用 input 還是有些問題的,如下所示:

由于 input 輸入內容無法跟隨寬度自適應,所以有時候會出現文字被截斷的情況:

理想情況下,當輸入內容較多時,應該整體換行。如何實現呢?可以用普通的 div 來實現。

<div class="tags-content">
<tag>CSS<a class="tag-close"></a></tag>
<div class="tags-input" placeholder="添加標簽"></div>
</div>

可以通過添加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 就變成了這樣:

<div class="tags-content">
<div class="tags-input" placeholder="添加標簽"></div>
</div>

這種情況,就僅剩輸入框唯一元素了,唯一元素可以通過: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 + '<a class="kalos-tag-close"></a>';
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 來行代碼,這里總結一下實現要點:

  • 普通 div 元素輸入純文本可以使用 -webkit-user-modify: read-write-plaintext-only
  • 普通 div 元素輸入可以自適應內容寬度
  • 普通 div 元素輸入框的 placeholder 占位可以通過 :empty 結合偽元素實現
  • 回車事件需要阻止默認事件,不然會換行
  • 在一個元素的前面新增元素可以用 before 方法
  • 刪除一個元素的前面一個元素,可以用 previousElementSibling.remove 方法
  • 給動態生成的元素綁定事件可以用事件委托的方式

在各種框架大行其道的氛圍下,有些原生的屬性和方法可能都不太關注了,這也不失為是一種損失。當然,我本身也是各種框架都會用,特別是大型、復雜的交互頁面,一般比較小的交互,比如文章這個例子,在 ant design 中有相關的組件,也使用過,因為整體 UI 全是這種風格,設計也是按照這個設計的。后來需要單獨開發一個 chrome 插件,也用到了這樣一個交互,但是僅僅用了這樣一個組件,引入整個框架就過于累贅了,所以還是選擇直接原生實現,簡單方便。

責任編輯:武曉燕 來源: 前端偵探
相關推薦

2020-09-24 14:06:19

Vue

2017-09-11 17:46:48

設計

2024-06-13 15:43:04

2023-05-22 09:10:53

CSSloading 效

2025-05-07 08:10:43

2025-10-24 08:13:17

2023-04-17 09:08:27

CSS計時器

2011-07-22 15:32:53

iPhone 按鈕 對話框

2022-10-20 11:49:49

JS動畫幀,CSS

2023-10-20 08:02:25

圖形編輯器前端

2021-09-27 14:44:48

鴻蒙HarmonyOS應用

2016-10-19 14:54:46

css選擇器css3css

2021-09-13 06:03:42

CSS 技巧搜索引擎

2024-10-12 16:38:09

2011-10-25 09:28:30

Node.js

2020-08-07 10:40:56

Node.jsexpress前端

2019-03-07 14:45:07

聊天工具富文本輸入框前端

2023-08-03 09:12:02

2022-11-07 11:27:00

JS游戲開發

2020-10-29 16:00:03

Node.jsweb前端
點贊
收藏

51CTO技術棧公眾號

国产一区二区三区成人| 五月天免费网站| 欧美片第1页| 国产女同性恋一区二区| 99精品在线直播| 中文字幕高清在线免费播放| 久久久久av| 精品网站999www| 国产欧美精品一二三| 两个人看的在线视频www| 国产精品久久二区二区| 久久久久无码国产精品一区| 国产老妇伦国产熟女老妇视频| 亚洲国产导航| 精品国产区一区二区三区在线观看| 白嫩情侣偷拍呻吟刺激| 成人51免费| 一本色道久久综合亚洲精品按摩 | 一个色免费成人影院| 678五月天丁香亚洲综合网| 免费毛片小视频| av激情在线| 国产精品入口麻豆原神| 欧美国产一二三区| 高潮毛片7777777毛片| 久久精品免费看| 欧亚精品在线观看| 成年人免费看毛片| 欧美一区免费| 在线观看欧美日韩| caopeng视频| 色吊丝一区二区| 日韩欧美国产麻豆| 蜜桃福利午夜精品一区| 国产黄色精品| 欧美亚洲动漫制服丝袜| 免费在线观看的av网站| 国产高清视频色在线www| 一区二区三区成人| 91免费国产精品| 成人午夜在线影视| 国产精品白丝在线| 伊人久久大香线蕉av一区| 国产小视频在线| 久久综合色婷婷| 久久精品人成| 你懂的视频在线免费| 26uuu国产一区二区三区| 国产一区在线免费观看| 天天干视频在线| 丰满少妇久久久久久久| 国产成人精品一区二区三区福利| 午夜精品久久久久久久第一页按摩| 久久国产欧美日韩精品| 91久久国产精品| 国产欧美日韩成人| 粉嫩欧美一区二区三区高清影视| 91免费版黄色| 亚洲免费成人网| 成人深夜在线观看| 好看的日韩精品视频在线| 四季av日韩精品一区| 成人免费精品视频| 国产欧美一区二区视频| 天天干在线观看| 久久众筹精品私拍模特| 欧洲亚洲一区| 蜜芽在线免费观看| 亚洲综合免费观看高清完整版 | 国产精品乱看| 国产精品成人品| 中文字幕人妻色偷偷久久| 久久99精品久久久久久国产越南| 成人国产精品久久久| 国产精品久久婷婷| 不卡的av网站| 日韩三级电影| 3d玉蒲团在线观看| 韩曰欧美视频免费观看| 日本xxxx黄色| 亚洲精品黑牛一区二区三区| 日韩激情在线视频| а天堂中文在线资源| 欧美日韩天堂| 人妖精品videosex性欧美| 伊人久久成人网| 国产精品影音先锋| 久草一区二区| 天堂资源在线中文| 午夜一区二区三区在线观看| 天天操天天爱天天爽| 婷婷视频一区二区三区| 亚洲全黄一级网站| 国产精品 欧美激情| 欧美亚洲一区| 亚洲va电影大全| 你懂的在线播放| 一区二区三区成人在线视频| 大香煮伊手机一区| 亚洲一区二区三区免费| 亚洲一区二区国产| 日韩伦人妻无码| 国产一区二区三区免费播放 | 亚洲三区在线播放| 成人免费视频在线观看| 久久久久狠狠高潮亚洲精品| 涩爱av色老久久精品偷偷鲁 | av网站导航在线观看免费| 欧美三级免费观看| www.美色吧.com| 99精品视频精品精品视频| 欧美亚洲国产视频| 亚洲精品一区二区口爆| 国产精品久99| 国产美女三级视频| 久久99国产精品久久99大师| 精品国偷自产在线视频| 成人黄色三级视频| 91亚洲精品久久久蜜桃网站| 嫩草影院中文字幕| 日韩av黄色| 国产一区二区三区四区福利| 特黄视频免费看| 99视频精品免费视频| 九九久久九九久久| 欧美成人app| 亚洲欧美日韩网| www.国产成人| 成人h版在线观看| 国产爆乳无码一区二区麻豆| 国产精品igao视频网网址不卡日韩| 亚洲午夜精品久久久久久性色| 在线观看精品国产| 成人美女视频在线观看18| 最新欧美日韩亚洲| 日韩成人精品一区二区三区| 爽爽爽爽爽爽爽成人免费观看| 亚洲精品一区二三区| 久久综合99re88久久爱| 精品国产成人av在线免| 亚洲欧洲av| 日本高清视频精品| 欧美美乳在线| 在线中文字幕一区二区| 国内精品卡一卡二卡三| 日韩va亚洲va欧美va久久| 日本午夜精品一区二区| 国产精品高清乱码在线观看| 亚洲性无码av在线| 在线观看中文字幕2021| 国产精品高清亚洲| 天天干天天曰天天操| 欧美在线观看天堂一区二区三区| 亚洲最大av网站| 日本在线观看高清完整版| 欧美xxxx老人做受| 日韩欧美亚洲国产| 91在线精品一区二区| 99福利在线观看| 精品国产乱码久久久久久1区2匹| 国产成人精品午夜| 午夜伦理在线| 日韩欧美激情在线| 久久不卡免费视频| 久久久精品免费网站| 午夜在线观看av| 中文字幕免费精品| 国产精品亚洲综合| 成人午夜视屏| 精品国产欧美一区二区三区成人| www.我爱av| 欧美日韩国产页| 亚洲av无码国产精品麻豆天美| 日本成人在线不卡视频| 2021狠狠干| 免费成人蒂法| 国产精品小说在线| 美女网站视频在线| 亚洲男人天堂古典| 国产模特av私拍大尺度| 黑人巨大精品欧美一区二区免费| 精品无码人妻一区二区免费蜜桃| 激情综合色综合久久| 国产综合中文字幕| 波多野结衣在线观看一区二区| 国产专区欧美专区| 黄在线观看免费网站ktv| 最新的欧美黄色| 三级网站在线看| 欧美日韩一区二区三区四区| 久久久久久久99| 欧美激情一区二区| 日韩精品人妻中文字幕有码| 老司机精品视频导航| 欧美激情视频免费看| 国产精品精品| 欧美日韩一区在线播放| 试看120秒一区二区三区| 欧美一区三区三区高中清蜜桃| 日本不卡不卡| 亚洲欧美综合精品久久成人| 精品人妻午夜一区二区三区四区 | 亚洲图区在线| 97操在线视频| 成人免费毛片嘿嘿连载视频…| 欧美高清第一页| 日韩在线免费电影| 亚洲欧洲午夜一线一品| 成人黄色免费视频| 欧美图片一区二区三区| 亚洲男人第一av| 亚洲综合自拍偷拍| frxxee中国xxx麻豆hd| 久久噜噜亚洲综合| 国产精品一区二区在线免费观看| 精品一区二区在线观看| 日本精品www| 亚洲少妇在线| 成人黄色大片网站| 欧美日本中文| 最新av在线免费观看| 成人影院在线| 欧美综合77777色婷婷| 亚洲专区视频| 另类欧美小说| 日韩深夜影院| 国产亚洲自拍偷拍| 国产乱人伦精品一区| 91九色蝌蚪成人| 99视频有精品高清视频| 成人精品久久久| 久久亚洲精品人成综合网| 国产精品福利在线| 666av成人影院在线观看| 欧美一级片久久久久久久| 成人女同在线观看| 久久久免费精品视频| 在线看一级片| 欧美激情va永久在线播放| 视频在线这里都是精品| 日韩性xxxx爱| 免费的黄网站在线观看| 日韩视频精品在线| 久久久久久久久免费视频| 久久精品国产一区二区三区| 麻豆传媒在线观看| 欧美成人精品在线视频| 午夜成年人在线免费视频| 色与欲影视天天看综合网| 免费在线看电影| 91极品视频在线| 高清不卡亚洲| 国产日韩专区在线| 激情综合婷婷| 国产精品乱码视频| 欧美电影完整版在线观看| 蜜桃狠狠色伊人亚洲综合网站| 国产91一区| 曰韩不卡视频| 黄色日韩精品| 日日橹狠狠爱欧美超碰| 日韩和欧美一区二区| 超碰成人在线播放| 成人性生交大片| 37p粉嫩大胆色噜噜噜| 国产欧美一区在线| 黄色a级片在线观看| 亚洲成精国产精品女| 亚洲大片免费观看| 欧美精品一二三| 色婷婷av一区二区三| 亚洲图片欧美午夜| av毛片在线免费看| 青青草成人在线| 91精品亚洲一区在线观看| 国产手机精品在线| 欧美国产偷国产精品三区| 国内少妇毛片视频| 玖玖视频精品| 欧美体内she精高潮| 久久综合九色综合久久久精品综合| 国产精品久久久视频| 一区二区成人在线观看| 五月激情六月丁香| 91精品国产综合久久香蕉麻豆 | 精品视频在线播放一区二区三区 | 亚洲青色在线| 国产免费又粗又猛又爽| 成人免费毛片a| 在线免费观看视频| 香蕉成人啪国产精品视频综合网| 中文字幕精品无码亚| 亚洲国产精品电影在线观看| 最新真实国产在线视频| 97av在线视频| 日本精品视频| 欧美精品在线一区| 国产精品啊v在线| 免费涩涩18网站入口| av一区二区不卡| 三级av在线免费观看| 日本精品视频一区二区| 老司机午夜福利视频| 久久久精品国产| 成人免费av电影| 国产一区自拍视频| 欧美日本一区二区视频在线观看| 丝袜制服一区二区三区| 97aⅴ精品视频一二三区| 欧美三级小视频| 欧美日本在线看| 第三区美女视频在线| 668精品在线视频| 哺乳挤奶一区二区三区免费看| 一本久久a久久精品vr综合| 久久人人97超碰国产公开结果| 久久久久亚洲av无码网站| 亚洲欧美另类综合偷拍| 中文字幕永久在线观看| 亚洲欧美自拍一区| 欧美人与性动交xxⅹxx| 国产伦精品一区二区三毛| 中文字幕午夜精品一区二区三区 | 欧洲精品在线播放| 狠狠色丁香婷婷综合| 久久日免费视频| 日韩欧美999| 午夜av免费观看| 久久久久久久999精品视频| 日本高清久久| 无颜之月在线看| 国产精品1024| www.色小姐com| 日韩一区二区免费视频| 麻豆传媒视频在线| 国产日韩中文字幕| 天天射综合网视频| 高清av免费看| 中文字幕在线视频一区| 一级特黄色大片| 久久久成人精品| 国产一区二区三区| 女女百合国产免费网站| 国产精品一区二区久激情瑜伽| 国语对白在线播放| 日韩精品中文字幕一区| 蜜臀av在线| 鲁丝一区二区三区免费| 国产手机视频一区二区| 性欧美丰满熟妇xxxx性仙踪林| 日韩欧美国产免费播放| 韩国三级在线观看久| 国产剧情久久久久久| 夜间精品视频| 精品国产乱码久久久久夜深人妻| 亚洲韩国精品一区| 神马精品久久| 国产精品美女免费看| 91久久久精品国产| 国产xxx在线观看| 欧美性xxxx极品hd满灌| 国产免费av在线| 成人免费视频a| 亚洲视频日本| av无码av天天av天天爽| 欧美三级电影在线观看| 麻豆视频在线| 国产在线精品一区二区三区》| 性久久久久久| 在线观看天堂av| 欧美精品一区二区三区在线播放| 性欧美又大又长又硬| 亚洲欧洲免费无码| 国产成人av电影免费在线观看| 国产成人一区二区三区影院在线| 亚洲天堂av在线播放| 亚洲一区二区av| 凹凸国产熟女精品视频| 国产精品沙发午睡系列990531| 99在线小视频| 日本久久久久久久久久久| 国产精品黑丝在线播放| 亚洲精品乱码久久| 欧美日韩国产综合一区二区三区| 欧美高清另类hdvideosexjaⅴ| 鲁鲁视频www一区二区| 国产一区二区三区免费看| 日本高清不卡码| 美女精品久久久| 欧美**vk| 亚洲国产精品第一页| 欧美唯美清纯偷拍| 欧美大片黄色| 制服丝袜综合日韩欧美| 99r精品视频| av中文在线观看| 国产91色在线播放| 午夜日韩激情| 一级二级黄色片| 亚洲精品黄网在线观看|