如何用纯JavaScript实现以div替代option的自定义依赖下拉菜单
自定义依赖下拉菜单解决方案
下面是基于div实现的自定义依赖下拉菜单,完全替代原select/option结构,保留原有功能的同时支持自定义样式:
HTML结构
替换原表单中的select元素,使用div构建自定义下拉,并添加隐藏input用于表单提交:
<div class="consultation-section" id="book-consultation"> <div class="container"> <div class="consultation-heading"> <h2 class="heading-h text-white">Book A Consultation</h2> <p class="heading-p text-white">Book A Consultation For Your Project & We'll Reach You Soon</p> <hr class="heading-line-one"> </div> <div class="consultation-form"> <form id="consult-form" class="consult-form"> <!-- 主下拉菜单 --> <div class="custom-dropdown"> <button type="button" class="dropdown-trigger" id="main-trigger">Select Project Type</button> <div class="dropdown-options" id="main-options"> <div class="dropdown-option" data-value="web-dev">Web Development</div> <div class="dropdown-option" data-value="grp-dsg">Graphic Designing</div> <div class="dropdown-option" data-value="dgt-mkt">Digital Marketing</div> </div> <!-- 隐藏input用于表单提交 --> <input type="hidden" name="project-type" id="project-type" required> </div> <!-- Web开发子菜单 --> <div class="custom-dropdown sub-dropdown" id="web-section" style="display: none;"> <button type="button" class="dropdown-trigger">Select Sub-Project Type</button> <div class="dropdown-options"> <div class="dropdown-option" data-value="static">► Static Website Development</div> <div class="dropdown-option" data-value="dynamic">► Dynamic Website Development</div> <div class="dropdown-option" data-value="cms">► CMS Website Development</div> </div> <input type="hidden" name="sub-project-type" id="web-subtype" required> </div> <!-- 平面设计子菜单 --> <div class="custom-dropdown sub-dropdown" id="graphic-section" style="display: none;"> <button type="button" class="dropdown-trigger">Select Sub-Project Type</button> <div class="dropdown-options"> <div class="dropdown-option" data-value="banner">► Banner Designing</div> <div class="dropdown-option" data-value="logo">► Logo Designing</div> <div class="dropdown-option" data-value="mockup">► Mockup Designing</div> </div> <input type="hidden" name="sub-project-type" id="graphic-subtype" required> </div> <!-- 数字营销子菜单 --> <div class="custom-dropdown sub-dropdown" id="marketing-section" style="display: none;"> <button type="button" class="dropdown-trigger">Select Sub-Project Type</button> <div class="dropdown-options"> <div class="dropdown-option" data-value="onpage-seo">► One-Page SEO</div> <div class="dropdown-option" data-value="offpage-seo">► Off-Page SEO</div> <div class="dropdown-option" data-value="brand-promotion">► Brand Promotion</div> </div> <input type="hidden" name="sub-project-type" id="marketing-subtype" required> </div> <!-- 保持原按钮 --> <button type="submit" class="consult-btn">Submit</button> </form> </div> </div> </div>
CSS样式
添加自定义下拉的样式,兼容原页面风格,同时实现下拉动画:
.consultation-section { background-color: #323757; height: 100%; } .consultation-section .container { max-width: 90%; margin: 0 auto; height: 100%; } .consultation-heading { padding-top: 2.3rem; } .heading-h, .heading-p { text-align: center; color: #fff; } .consultation-form { margin-top: 3.1rem; padding-bottom: 2rem; } /* 自定义下拉核心样式 */ .custom-dropdown { position: relative; margin-bottom: 30px; width: 100%; } .dropdown-trigger { width: 100%; height: 55px; background: #fff; color: #323757; padding-left: 10px; border: 1px solid #fff; text-align: left; cursor: pointer; display: flex; align-items: center; justify-content: space-between; padding-right: 15px; font-size: 16px; } /* 添加下拉箭头 */ .dropdown-trigger::after { content: "▼"; font-size: 12px; transition: transform 0.3s ease; } .dropdown-trigger.open::after { transform: rotate(180deg); } .dropdown-options { position: absolute; top: 100%; left: 0; right: 0; background: #fff; border: 1px solid #eee; max-height: 0; overflow: hidden; transition: max-height 0.3s ease; z-index: 100; } .dropdown-options.open { max-height: 200px; } .dropdown-option { padding: 12px 10px; color: #323757; cursor: pointer; transition: background-color 0.2s ease; } .dropdown-option:hover { background-color: #f0f0f0; } .dropdown-option.selected { background-color: #e8576f; color: #fff; } /* 原有样式保留 */ .consult-btn { font-size: 17px; font-weight: 550; text-transform: uppercase; background: #e8576f; display: block; margin: 0 auto; margin-top: 30px; max-width: 150px; width: 100%; color: #fff; height: 47px; line-height: 47px; outline: none; border: none; text-align: center; cursor: pointer; transition: ease-in all 0.5s; } .consult-btn:hover { color: #e8576f; background-color: #fff; }
JavaScript逻辑
实现下拉展开/收起、依赖显示子菜单、选中状态同步和表单值存储:
document.addEventListener('DOMContentLoaded', function() { // 获取所有下拉元素 const mainTrigger = document.getElementById('main-trigger'); const mainOptions = document.getElementById('main-options'); const subDropdowns = document.querySelectorAll('.sub-dropdown'); const projectTypeInput = document.getElementById('project-type'); // 主下拉菜单点击事件 mainTrigger.addEventListener('click', function() { mainOptions.classList.toggle('open'); this.classList.toggle('open'); }); // 主选项点击处理 mainOptions.querySelectorAll('.dropdown-option').forEach(option => { option.addEventListener('click', function() { const value = this.dataset.value; const text = this.textContent; // 更新主按钮文本 mainTrigger.textContent = text; // 存储表单值 projectTypeInput.value = value; // 收起主菜单 mainOptions.classList.remove('open'); mainTrigger.classList.remove('open'); // 隐藏所有子菜单 subDropdowns.forEach(dropdown => { dropdown.style.display = 'none'; // 重置子菜单选中状态 const trigger = dropdown.querySelector('.dropdown-trigger'); const options = dropdown.querySelector('.dropdown-options'); const input = dropdown.querySelector('input'); trigger.textContent = 'Select Sub-Project Type'; options.querySelectorAll('.dropdown-option').forEach(opt => opt.classList.remove('selected')); input.value = ''; }); // 显示对应子菜单 const targetDropdown = document.getElementById(`${value.replace('-', '')}-section`); if (targetDropdown) { targetDropdown.style.display = 'block'; } }); }); // 子下拉菜单通用处理 document.querySelectorAll('.sub-dropdown').forEach(dropdown => { const trigger = dropdown.querySelector('.dropdown-trigger'); const options = dropdown.querySelector('.dropdown-options'); const input = dropdown.querySelector('input'); trigger.addEventListener('click', function() { options.classList.toggle('open'); this.classList.toggle('open'); }); options.querySelectorAll('.dropdown-option').forEach(option => { option.addEventListener('click', function() { const value = this.dataset.value; const text = this.textContent; // 更新子按钮文本 trigger.textContent = text; // 存储表单值 input.value = value; // 设置选中状态 options.querySelectorAll('.dropdown-option').forEach(opt => opt.classList.remove('selected')); this.classList.add('selected'); // 收起子菜单 options.classList.remove('open'); trigger.classList.remove('open'); }); }); }); // 点击页面其他区域关闭所有下拉 document.addEventListener('click', function(e) { if (!e.target.closest('.custom-dropdown')) { document.querySelectorAll('.dropdown-options').forEach(opt => opt.classList.remove('open')); document.querySelectorAll('.dropdown-trigger').forEach(trig => trig.classList.remove('open')); } }); });
关键功能说明
- 自定义样式支持:完全基于div和button实现,可通过CSS自由修改按钮、选项的颜色、间距、动画等样式
- 依赖显示逻辑:主菜单选中后自动显示对应子菜单,隐藏其他子菜单
- 表单兼容性:通过隐藏input存储选中值,确保表单提交时能获取到选择的项目类型和子类型
- 交互体验优化:添加下拉箭头旋转动画、选项hover效果、点击外部关闭下拉等功能
内容的提问来源于stack exchange,提问作者MY CHANNEL
相关产品推荐
相关产品推荐

