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

如何用HTML/CSS/JS实现带图片、支持搜索的币种select下拉组件

带图标、输入即搜索功能的币种选择组件实现

原生<select>标签无法自定义内置搜索框、选项前置图标,直接通过HTML+CSS+JS模拟自定义组件即可1:1还原参考效果,三个参考状态如下:

  • select默认状态
  • 点击select后展开、带搜索入口的状态
  • 输入关键词实时过滤的搜索状态

核心实现逻辑

  • 用普通div模拟选择器触发器,展示当前选中项的币种图标、名称、下拉箭头
  • 下拉面板内置搜索输入框、币种选项列表,默认隐藏,点击触发器时展开
  • 监听搜索框输入事件,实时匹配币种名称过滤不相关选项
  • 监听全局点击事件,点击组件外部区域时自动收起下拉面板
  • 点击选项后自动回填选中值到触发器,重置搜索状态

完整可运行代码

HTML 结构

<!-- 自定义币种选择组件 -->
<div class="crypto-select">
  <!-- 选择触发器,对应默认关闭状态 -->
  <div class="select-trigger">
    <img src="https://s2.coinmarketcap.com/static/img/coins/64x64/1.png" alt="BTC" class="selected-icon">
    <span class="selected-name">Bitcoin (BTC)</span>
    <span class="arrow">▼</span>
  </div>
  <!-- 下拉面板 -->
  <div class="select-dropdown">
    <input type="text" class="search-input" placeholder="Type to search...">
    <div class="options-list">
      <!-- 预置币种选项,可按需扩展 -->
      <div class="option" data-icon="https://s2.coinmarketcap.com/static/img/coins/64x64/1.png" data-name="Bitcoin (BTC)">
        <img src="https://s2.coinmarketcap.com/static/img/coins/64x64/1.png" alt="BTC">
        <span>Bitcoin (BTC)</span>
      </div>
      <div class="option" data-icon="https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png" data-name="Ethereum (ETH)">
        <img src="https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png" alt="ETH">
        <span>Ethereum (ETH)</span>
      </div>
      <div class="option" data-icon="https://s2.coinmarketcap.com/static/img/coins/64x64/825.png" data-name="Tether (USDT)">
        <img src="https://s2.coinmarketcap.com/static/img/coins/64x64/825.png" alt="USDT">
        <span>Tether (USDT)</span>
      </div>
      <div class="option" data-icon="https://s2.coinmarketcap.com/static/img/coins/64x64/1839.png" data-name="BNB (BNB)">
        <img src="https://s2.coinmarketcap.com/static/img/coins/64x64/1839.png" alt="BNB">
        <span>BNB (BNB)</span>
      </div>
      <div class="option" data-icon="https://s2.coinmarketcap.com/static/img/coins/64x64/52.png" data-name="XRP (XRP)">
        <img src="https://s2.coinmarketcap.com/static/img/coins/64x64/52.png" alt="XRP">
        <span>XRP (XRP)</span>
      </div>
    </div>
  </div>
</div>

CSS 样式

.crypto-select {
  position: relative;
  width: 320px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* 触发器样式 */
.select-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
  transition: border-color 0.2s;
}
.select-trigger:hover {
  border-color: #4096ff;
}
.selected-icon {
  width: 20px;
  height: 20px;
  border-radius: 50%;
}
.selected-name {
  flex: 1;
  font-size: 14px;
}
.arrow {
  font-size: 12px;
  color: #999;
  transition: transform 0.2s;
}
/* 展开状态箭头翻转 */
.crypto-select.open .arrow {
  transform: rotate(180deg);
}

/* 下拉面板样式 */
.select-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  width: 100%;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  background: #fff;
  box-shadow: 0 6px 16px rgba(0,0,0,0.08);
  display: none;
  z-index: 100;
}
.crypto-select.open .select-dropdown {
  display: block;
}

/* 搜索框样式 */
.search-input {
  width: 100%;
  padding: 10px 12px;
  border: none;
  border-bottom: 1px solid #f0f0f0;
  border-radius: 6px 6px 0 0;
  font-size: 14px;
  outline: none;
  box-sizing: border-box;
}
.search-input:focus {
  border-bottom-color: #4096ff;
}

/* 选项列表样式 */
.options-list {
  max-height: 280px;
  overflow-y: auto;
}
.option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  cursor: pointer;
  font-size: 14px;
}
.option:hover {
  background: #f5f5f5;
}
.option img {
  width: 20px;
  height: 20px;
  border-radius: 50%;
}
/* 搜索时隐藏不匹配选项 */
.option.hidden {
  display: none;
}

JavaScript 交互逻辑

// 初始化组件
const select = document.querySelector('.crypto-select');
const trigger = select.querySelector('.select-trigger');
const dropdown = select.querySelector('.select-dropdown');
const searchInput = select.querySelector('.search-input');
const options = select.querySelectorAll('.option');
const selectedIcon = select.querySelector('.selected-icon');
const selectedName = select.querySelector('.selected-name');

// 1. 触发器点击:切换面板显隐
trigger.addEventListener('click', (e) => {
  e.stopPropagation();
  select.classList.toggle('open');
  if (select.classList.contains('open')) {
    searchInput.value = '';
    // 展开时重置所有选项显示,自动聚焦搜索框
    options.forEach(opt => opt.classList.remove('hidden'));
    searchInput.focus();
  }
});

// 2. 输入即搜索:实时过滤选项
searchInput.addEventListener('input', (e) => {
  const keyword = e.target.value.trim().toLowerCase();
  options.forEach(opt => {
    const text = opt.dataset.name.toLowerCase();
    opt.classList.toggle('hidden', !text.includes(keyword));
  });
});

// 3. 点击选项:选中回填
options.forEach(opt => {
  opt.addEventListener('click', () => {
    selectedIcon.src = opt.dataset.icon;
    selectedName.textContent = opt.dataset.name;
    select.classList.remove('open');
  });
});

// 4. 点击外部区域关闭面板
document.addEventListener('click', () => {
  select.classList.remove('open');
});
// 阻止面板内部点击冒泡触发全局关闭
dropdown.addEventListener('click', (e) => {
  e.stopPropagation();
});

扩展说明

  • 如果需要接入动态币种数据,只需要把预置的option节点替换成接口数据渲染即可,逻辑无需改动
  • 可按需扩展键盘上下选择、回车选中、空状态提示等功能,基础交互已经和参考效果完全对齐
  • 币种图标可替换为项目本地预置图片资源,避免跨域或资源失效问题

内容的提问来源于stack exchange,提问作者Epifânio Francisco

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:48:13