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

select绑定onchange与onclick后click事件触发两次及嵌套选项显示问题

Got it, let's fix this problem step by step!

First, let's figure out why your click event is firing twice: most likely, it's due to event bubbling—when you click an option, the click event bubbles up to the select element itself, and if you've bound the click handler directly to the select, it might trigger once when you open the dropdown, and again when you select an option. Alternatively, you might have accidentally bound the click event multiple times somewhere in your code.

But here's the thing: you don't even need a click event for this task. The change event is perfect for handling selection changes, and we can pair it with focus/blur events to toggle between the indented dropdown options and the clean selected display.

Here's a solid solution:

Step 1: Set up your HTML with indented options

First, create your select with properly indented option text (spaces work fine for nesting):

<select id="nestedSelect">
  <option value="parent">Parent Item</option>
  <option value="child1">  Child Item 1</option>
  <option value="child2">  Child Item 2</option>
  <option value="grandchild">    Grandchild Item</option>
</select>

Step 2: Store original indented text with data attributes

On page load, save each option's original indented text to a data attribute—this lets us switch back to the indented version when the dropdown opens:

$(document).ready(function() {
  // Save original indented text for every option
  $('#nestedSelect option').each(function() {
    $(this).data('originalText', $(this).text());
  });
});

Step 3: Toggle text on focus/blur/change

  • When the select gets focus (user opens the dropdown), restore all options to their original indented text so the nested structure is visible.
  • When the select loses focus or a change happens (user selects an option), trim the text of the selected option to show the clean, unindented label.
// Restore indented text when dropdown opens
$('#nestedSelect').on('focus', function() {
  $(this).find('option').each(function() {
    $(this).text($(this).data('originalText'));
  });
});

// Show trimmed text when an option is selected or dropdown closes
$('#nestedSelect').on('change blur', function() {
  const selectedOpt = $(this).find('option:selected');
  selectedOpt.text(selectedOpt.data('originalText').trim());
});

Why this works:

  • No more duplicate click events because we're using the right events for the job: focus/blur handle dropdown state, and change handles selection.
  • The data attribute ensures we never lose the original indented text, so we can switch between views seamlessly.
  • Users see the nested structure when browsing options, and a clean, unindented label once they make a selection.

If you still wanted to debug your original click issue, check for:

  • Accidentally binding the click event multiple times (e.g., inside a function that runs more than once)
  • Not stopping event propagation if you're binding to both the select and options (though this isn't necessary with the solution above)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:55:18