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

如何用jQuery将含optgroup的select转换为对应结构的ul/li?

Hey there! Let's fix that duplicate option issue you're dealing with when converting <select> elements to custom dropdowns. I’ve run into this exact problem before, so I know exactly where you might be slipping up.

The Root Cause

Your current code is probably grabbing all <option> elements in the entire <select> every time you process an <optgroup>, which is why every group ends up with every option. The fix is simple: you need to only target the options that are direct children of the current <optgroup> you’re processing.

Solution Code

Here’s a clean, targeted jQuery implementation that handles both <optgroup> and standalone <option> cases correctly:

// Iterate over each target select element
$('select.custom-select').each(function() {
  const $originalSelect = $(this);
  // Create a container for our custom dropdown
  const $customDropdown = $('<div class="custom-dropdown-container"></div>');

  // Check if the select has optgroups
  if ($originalSelect.find('optgroup').length) {
    // Loop through each optgroup in the current select
    $originalSelect.find('optgroup').each(function() {
      const $currentOptgroup = $(this);
      // Create a UL to represent the optgroup
      const $groupList = $('<ul class="dropdown-group" data-group-label="' + $currentOptgroup.attr('label') + '"></ul>');
      
      // ONLY grab options inside THIS optgroup (not all options in the select!)
      $currentOptgroup.find('option').each(function() {
        const $currentOption = $(this);
        const $listItem = $('<li class="dropdown-item" data-value="' + $currentOption.val() + '">' + $currentOption.text() + '</li>');
        $groupList.append($listItem);
      });

      // Add the group to our custom dropdown
      $customDropdown.append($groupList);
    });
  } else {
    // No optgroups? Just convert all options directly to list items
    $originalSelect.find('option').each(function() {
      const $currentOption = $(this);
      const $listItem = $('<li class="dropdown-item" data-value="' + $currentOption.val() + '">' + $currentOption.text() + '</li>');
      $customDropdown.append($listItem);
    });
  }

  // Insert the custom dropdown after the original select, then hide the original
  $originalSelect.after($customDropdown);
  $originalSelect.hide();
});

Key Fix Explained

The critical line here is $currentOptgroup.find('option') — by using $currentOptgroup as the parent selector instead of $originalSelect, we only pull options that belong to the specific <optgroup> we’re currently converting. This eliminates the duplicate options across groups.

Bonus: Basic CSS for the Custom Dropdown

To make it look like a proper dropdown, add this simple styling:

.custom-dropdown-container {
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 6px;
  max-height: 250px;
  overflow-y: auto;
  width: 200px;
}

.dropdown-group {
  list-style: none;
  padding: 0;
  margin: 8px 0;
}

.dropdown-group::before {
  content: attr(data-group-label);
  font-weight: 600;
  color: #555;
  padding: 4px 0;
  display: block;
  border-bottom: 1px solid #eee;
}

.dropdown-item {
  padding: 4px 8px;
  cursor: pointer;
  border-radius: 2px;
}

.dropdown-item:hover {
  background-color: #f5f5f5;
}

This will give you a clean, functional custom dropdown that respects your original <optgroup> structure without duplicate options.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:00:03