You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持多类型标签的tags-input输入框?附参考示例

我刚好做过类似的标签输入组件,给你一个完整的实现示例,完全匹配你提到的需求——输入时展示不同类型的候选标签,选中后还能通过样式区分标签类型。下面是可直接运行的代码:

实现带分类标签的Tags Input组件

1. HTML 结构

先搭建基础的DOM结构,包含已选标签容器、输入框和候选下拉列表:

<div class="tags-input-container">
  <div class="selected-tags" id="selectedTags"></div>
  <input 
    type="text" 
    class="tags-input" 
    id="tagsInput" 
    placeholder="输入品牌/车型..."
  >
  <div class="tag-suggestions" id="tagSuggestions"></div>
</div>

2. CSS 样式

给不同类型的标签设置差异化样式,同时美化整个输入区域:

.tags-input-container {
  width: 400px;
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 8px;
  font-family: Arial, sans-serif;
}

.selected-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
}

.tag-item {
  padding: 4px 8px;
  border-radius: 4px;
  color: white;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.tag-item .remove-tag {
  cursor: pointer;
  font-weight: bold;
}

/* 不同类型标签的样式 */
.tag-brand {
  background-color: #2563eb;
}

.tag-model {
  background-color: #16a34a;
}

.tags-input {
  width: 100%;
  border: none;
  outline: none;
  font-size: 14px;
  padding: 4px 0;
}

.tag-suggestions {
  margin-top: 8px;
  border-top: 1px solid #eee;
  padding-top: 8px;
  max-height: 200px;
  overflow-y: auto;
}

.suggestion-item {
  padding: 6px 8px;
  cursor: pointer;
  border-radius: 4px;
  font-size: 14px;
  margin-bottom: 4px;
}

.suggestion-item:hover {
  background-color: #f3f4f6;
}

/* 候选标签也区分类型 */
.suggestion-brand {
  border-left: 3px solid #2563eb;
}

.suggestion-model {
  border-left: 3px solid #16a34a;
}

3. JavaScript 逻辑

处理输入过滤、标签选中、删除等核心交互:

// 模拟不同类型的标签数据,实际项目可以换成接口返回
const tagsData = [
  { id: 1, name: "丰田", type: "brand" },
  { id: 2, name: "本田", type: "brand" },
  { id: 3, name: "卡罗拉", type: "model" },
  { id: 4, name: "思域", type: "model" },
  { id: 5, name: "大众", type: "brand" },
  { id: 6, name: "朗逸", type: "model" }
];

const selectedTagsContainer = document.getElementById('selectedTags');
const tagsInput = document.getElementById('tagsInput');
const tagSuggestions = document.getElementById('tagSuggestions');

// 存储已选中的标签ID,避免重复选择
const selectedTagIds = new Set();

// 输入事件:过滤并显示候选标签
tagsInput.addEventListener('input', function(e) {
  const inputValue = e.target.value.toLowerCase();
  const filteredTags = tagsData.filter(tag => 
    tag.name.toLowerCase().includes(inputValue) && !selectedTagIds.has(tag.id)
  );
  
  renderSuggestions(filteredTags);
});

// 渲染候选标签列表
function renderSuggestions(tags) {
  tagSuggestions.innerHTML = '';
  if (tags.length === 0) {
    tagSuggestions.style.display = 'none';
    return;
  }
  tagSuggestions.style.display = 'block';
  
  tags.forEach(tag => {
    const suggestionItem = document.createElement('div');
    suggestionItem.className = `suggestion-item suggestion-${tag.type}`;
    suggestionItem.textContent = tag.name;
    suggestionItem.dataset.tagId = tag.id;
    suggestionItem.dataset.tagName = tag.name;
    suggestionItem.dataset.tagType = tag.type;
    
    // 点击候选标签,添加到已选列表
    suggestionItem.addEventListener('click', function() {
      addSelectedTag(tag.id, tag.name, tag.type);
      tagsInput.value = '';
      tagSuggestions.innerHTML = '';
      tagSuggestions.style.display = 'none';
    });
    
    tagSuggestions.appendChild(suggestionItem);
  });
}

// 添加已选标签
function addSelectedTag(id, name, type) {
  if (selectedTagIds.has(id)) return;
  
  const tagItem = document.createElement('div');
  tagItem.className = `tag-item tag-${type}`;
  tagItem.innerHTML = `
    ${name}
    <span class="remove-tag" data-tag-id="${id}">&times;</span>
  `;
  
  // 删除标签事件
  tagItem.querySelector('.remove-tag').addEventListener('click', function() {
    selectedTagIds.delete(id);
    tagItem.remove();
  });
  
  selectedTagsContainer.appendChild(tagItem);
  selectedTagIds.add(id);
}

// 点击页面其他区域,关闭候选列表
document.addEventListener('click', function(e) {
  if (!e.target.closest('.tags-input-container')) {
    tagSuggestions.style.display = 'none';
  }
});

关键说明

  • 标签类型区分:通过tag-brand和tag-model类来给不同类型的标签设置不同样式,你可以根据需求扩展更多类型
  • 重复选择限制:用Set存储已选中的标签ID,避免重复添加
  • 输入过滤:实时根据输入内容过滤候选标签,同时排除已选中的标签
  • 交互优化:点击候选标签自动添加,点击标签上的叉号删除,点击页面其他区域关闭候选列表

如果需要对接后端接口,只需要把tagsData替换成接口返回的标签数据即可,逻辑完全通用。

内容的提问来源于stack exchange,提问作者Allen Haley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:59:16