自定义Select组件优化:disabled状态下禁止展开UL/LI列表
Got it, let's tackle this problem! The issue right now is that your custom select's trigger (div.styledSelect) still opens the dropdown even when the original <select> has the disabled attribute. We need to sync the disabled state to your custom elements and block the click behavior when it's disabled.
Step 1: Sync Disabled State on Initialization
First, when setting up the custom select, check if the original <select> is disabled. If it is, add a disabled class to the styled trigger to mark it visually and functionally.
Step 2: Block Click Events for Disabled Selects
Modify the click handler on $styledSelect to exit early if the trigger has the disabled class.
Step 3: Add Visual Feedback (CSS)
Add some CSS to make the disabled select look unclickable, so users get a clear visual cue.
Modified Full Code
JavaScript
// Iterate over each select element $('select').each(function () { // Cache the number of options var $this = $(this), numberOfOptions = $(this).children('option').length; // Hides the select element $this.addClass('s-hidden'); // Wrap the select element in a div $this.wrap('<div class="select"></div>'); // Insert a styled div to sit over the top of the hidden select element $this.after('<div class="styledSelect"></div>'); // Cache the styled div var $styledSelect = $this.next('div.styledSelect'); // Show the first select option in the styled div $styledSelect.text($this.children('option').eq(0).text()); // --- New: Sync disabled state from original select --- if ($this.is(':disabled')) { $styledSelect.addClass('disabled'); } // Insert an unordered list after the styled div and also cache the list var $list = $('<ul />', { 'class': 'options' }).insertAfter($styledSelect); // Insert a list item into the unordered list for each select option for (var i = 0; i < numberOfOptions; i++) { $('<li />', { text: $this.children('option').eq(i).text(), rel: $this.children('option').eq(i).val() }).appendTo($list); } // Cache the list items var $listItems = $list.children('li'); // Show the unordered list when the styled div is clicked (also hides it if the div is clicked again) $styledSelect.click(function (e) { // --- New: Exit if the select is disabled --- if ($(this).hasClass('disabled')) return; e.stopPropagation(); $('div.styledSelect.active').each(function () { $(this).removeClass('active').next('ul.options').hide(); }); $(this).toggleClass('active').next('ul.options').toggle(); }); // Hides the unordered list when a list item is clicked and updates the styled div to show the selected list item // Updates the select element to have the value of the equivalent option $listItems.click(function (e) { e.stopPropagation(); $styledSelect.text($(this).text()).removeClass('active'); $this.val($(this).attr('rel')); $list.hide(); /* alert($this.val()); Uncomment this for demonstration! */ }); // Hides the unordered list when clicking outside of it $(document).click(function () { $styledSelect.removeClass('active'); $list.hide(); }); });
CSS (Add This)
/* Style for disabled custom select */ .styledSelect.disabled { opacity: 0.6; cursor: not-allowed; pointer-events: none; /* Optional: Prevents click events entirely */ }
Example Disabled HTML
<select id="selectbox1" disabled> <option value="">Select an option…</option> <option value="aye">Aye</option> <option value="eh">Eh</option> <option value="ooh">Ooh</option> <option value="whoop">Whoop</option> </select>
How This Works
- We check the original
<select>'sdisabledstate during initialization and apply adisabledclass to the styled trigger. - The click handler on
$styledSelectnow checks for this class and exits immediately if present, preventing the dropdown from opening. - The CSS styles make the disabled select look inactive, and
pointer-events: none(optional) adds an extra layer of protection against clicks.
If you ever need to dynamically enable/disable the select later (via JavaScript), just toggle the disabled attribute on the original <select> and sync the disabled class on $styledSelect accordingly!
内容的提问来源于stack exchange,提问作者Richa

