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

如何实现Select2多选组件跨选联动禁用?(jQuery)

解决Select2跨多选框互斥禁用的问题

我看了你的代码,问题主要出在事件绑定逻辑混乱和没有通知Select2更新UI这两点上,咱们一步步来修正:

问题分析

  • 嵌套事件绑定导致逻辑失效:你在change事件内部又绑定了select2:select和select2:unselect,这会导致每次触发change都会新增一次事件监听,不仅逻辑混乱,而且你维护的selections数组也没法正确同步选中状态。
  • 禁用原生option后未刷新Select2:Select2是基于原生select封装的,直接修改原生option的disabled属性后,Select2不会自动感知到变化,必须手动触发刷新才能让禁用状态在界面上生效。
  • 缺少取消选中时的恢复逻辑:你只处理了选中时禁用对应选项,但没写取消选中后恢复启用的代码,这样之前禁用的选项永远不会被放开。

修正后的完整代码

<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/js/select2.min.js"></script>

<span>Table Header</span>
<select id="tableHeader" class="select2 select2-multiple" style="width: 100%" multiple="multiple" data-placeholder="Choose">
<option value="Geo">Geo</option>
<option value="Region">Region</option>
<option value="Country">Country</option>
<option value="Order Numer">Order Numer</option>
<option value="Order Value">Order Value</option>
<option value="Brand">Brand</option>
<option value="Quantity">Quantity</option>
<option value="Price">Price</option>
<option value="Revenue">Revenue</option>
<option value="Currency">Currency</option>
<option value="Created Date">Created Date</option>
<option value="Created By">Created By</option>
</select>
<br>
<span>Table Body</span>
<select id="tableBody" class="select2 select2-multiple" style="width: 100%" multiple="multiple" data-placeholder="Choose">
<option value="Geo">Geo</option>
<option value="Region">Region</option>
<option value="Country">Country</option>
<option value="Order Numer">Order Numer</option>
<option value="Order Value">Order Value</option>
<option value="Brand">Brand</option>
<option value="Quantity">Quantity</option>
<option value="Price">Price</option>
<option value="Revenue">Revenue</option>
<option value="Currency">Currency</option>
<option value="Created Date">Created Date</option>
<option value="Created By">Created By</option>
</select>

<script>
$(document).ready(function() { 
    // 搜索匹配输入的函数
    function matchCustom(params, data) { 
        if ($.trim(params.term) === '') { 
            return data; 
        } 
        if (typeof data.text === 'undefined') { 
            return null; 
        } 
        if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) { 
            var modifiedData = $.extend({}, data, true); 
            modifiedData.text += ''; 
            return modifiedData; 
        } 
        return null; 
    } 

    // 初始化两个Select2
    $(".select2").select2({ 
        matcher: matchCustom 
    }); 

    // 封装一个通用函数:根据选中值禁用/启用另一个下拉框的选项
    function syncDisabledOptions(sourceSelectId, targetSelectId) {
        var selectedValues = $('#' + sourceSelectId).val() || []; // 获取源下拉框的选中值,为空则设为空数组
        var $targetSelect = $('#' + targetSelectId);

        // 先恢复所有选项为启用状态
        $targetSelect.find('option').prop('disabled', false);
        // 禁用选中值对应的选项
        selectedValues.forEach(function(val) {
            $targetSelect.find('option[value="' + val + '"]').prop('disabled', true);
        });

        // 通知Select2刷新UI,否则禁用状态不会显示
        $targetSelect.trigger('change');
    }

    // 监听tableHeader的选中变化
    $('#tableHeader').on('select2:select select2:unselect', function() {
        syncDisabledOptions('tableHeader', 'tableBody');
    });

    // 监听tableBody的选中变化
    $('#tableBody').on('select2:select select2:unselect', function() {
        syncDisabledOptions('tableBody', 'tableHeader');
    });
}); 
</script>

关键改进点

  • 使用Select2原生事件:直接监听select2:select和select2:unselect事件,这两个事件是Select2专门用于多选框选中/取消选中的,比原生change事件更精准。
  • 封装通用函数减少重复代码:把禁用/启用选项的逻辑抽成syncDisabledOptions函数,避免重复写两遍相同的代码,也更易维护。
  • 先恢复再禁用:每次处理前先把目标下拉框的所有选项恢复启用,再禁用需要排除的选项,确保逻辑不会出现残留的禁用状态。
  • 触发Select2刷新:修改原生option属性后,调用trigger('change')让Select2重新渲染UI,这样禁用状态才能在界面上显示出来。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 20:48:11