如何基于Promise返回数据实现适配任意Category与Type键的JavaScript三级联动动态下拉框
To create three dependent dropdowns where each selection filters the next one, we'll need to:
- Populate the initial dropdown with all available categories from your
ctisDatastructure. - Add event listeners to each dropdown to update the subsequent options based on the current selection.
- Reset child dropdowns whenever a parent selection changes to maintain consistency.
Here's a complete, working implementation that handles dynamic category/type keys (no hardcoding required):
Full Code
<html> <body> <script> const ctis = [ "Category1 / C1-Type1 / C1-T1-Item1", "Category1 / C1-Type1 / C1-T1-Item2", "Category1 / C1-Type1 / C1-T1-Item2", "Category1 / C1-Type1 / C1-T1-Item3", "Category1 / C1-Type2 / C1-T2-Item1", "Category1 / C1-Type2 / C1-T2-Item2", "Category1 / C1-Type2 / C1-T2-Item3", "Category2 / C2-Type1 / C2-T1-Item1", "Category2 / C2-Type1 / C2-T1-Item2", "Category2 / C2-Type1 / C2-T1-Item2", "Category2 / C2-Type1 / C2-T1-Item3", "Category2 / C2-Type2 / C2-T2-Item1", "Category2 / C2-Type2 / C2-T2-Item2", "Category2 / C2-Type2 / C2-T2-Item3", ]; // Build the hierarchical data structure (your existing reduce logic) const ctisData = ctis.reduce( (obj, line) => { const [category, type, item] = line.split(" / "); obj[category] = { ...obj[category] } obj[category][type] = [...new Set([...obj[category][type] || [], item])]; return obj; }, {}); // Helper function to create and populate dropdowns function createDropdown(id, defaultText) { const select = document.createElement('select'); select.id = id; // Add default option const defaultOpt = document.createElement('option'); defaultOpt.value = defaultText.toLowerCase(); defaultOpt.textContent = defaultText; select.appendChild(defaultOpt); document.body.appendChild(select); return select; } // Create the three dropdowns const categoryDropdown = createDropdown('mySelect', 'Category'); const typeDropdown = createDropdown('mySelect2', 'Type'); const itemDropdown = createDropdown('mySelect3', 'Item'); // Populate initial category options const categories = Object.keys(ctisData); categories.forEach(category => { const opt = document.createElement('option'); opt.value = category; opt.textContent = category; categoryDropdown.appendChild(opt); }); // Event listener for category selection categoryDropdown.addEventListener('change', () => { const selectedCategory = categoryDropdown.value; // Reset type and item dropdowns to default typeDropdown.innerHTML = '<option value="type">Type</option>'; itemDropdown.innerHTML = '<option value="item">Item</option>'; // If a valid category is selected, populate type dropdown if (selectedCategory !== 'category') { const types = Object.keys(ctisData[selectedCategory]); types.forEach(type => { const opt = document.createElement('option'); opt.value = type; opt.textContent = type; typeDropdown.appendChild(opt); }); } }); // Event listener for type selection typeDropdown.addEventListener('change', () => { const selectedCategory = categoryDropdown.value; const selectedType = typeDropdown.value; // Reset item dropdown to default itemDropdown.innerHTML = '<option value="item">Item</option>'; // If valid category and type are selected, populate item dropdown if (selectedCategory !== 'category' && selectedType !== 'type') { const items = ctisData[selectedCategory][selectedType]; items.forEach(item => { const opt = document.createElement('option'); opt.value = item; opt.textContent = item; itemDropdown.appendChild(opt); }); } }); </script> </body> </html>
Key Breakdown
1. Helper Function for Dropdown Creation
The createDropdown function streamlines creating dropdowns with a default option, so we don't repeat code for each select element.
2. Initial Population of Categories
We use Object.keys(ctisData) to get all dynamic category names (no hardcoding!) and add them to the first dropdown. This works even if your category keys change in the future.
3. Dynamic Updates on Selection
- Category Change: When a category is selected, we clear the type and item dropdowns to avoid invalid states. If a valid category is chosen, we fetch its associated types from
ctisData[selectedCategory]and populate the type dropdown. - Type Change: When a type is selected, we clear the item dropdown. If both a category and type are valid, we fetch the items from
ctisData[selectedCategory][selectedType]and populate the item dropdown.
4. Handling Default Selections
Whenever a parent dropdown is reset to its default option, all child dropdowns are also reset to their defaults. This ensures users can't select a type or item that doesn't belong to the currently chosen category.
This implementation is fully flexible—it adapts automatically to any category/type key values present in your ctisData structure.
内容的提问来源于stack exchange,提问作者Ryan Bell

