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

jQuery multiselect.js点击optgroup选中全部选项(含隐藏项)问题

问题:Multiselect插件点击Optgroup仅选中搜索可见选项失效

使用Multiselect插件优化多选体验,集成quicksearch搜索功能并开启selectableOptgroup选项后,点击optgroup时希望只选中搜索匹配后可见的选项(不匹配项被设置style='display: none'隐藏)。尝试用:visible和:not(:hidden)选择器筛选无效,点击optgroup仍会选中该组所有选项,包括隐藏项。

相关代码及结构

原选中逻辑代码

$selectableOptgroup.find('.ms-optgroup-label').on('click', function(){
  var values = $optgroup.children(':not(:selected, :disabled)').map(function(){ return $(this).val();}).get();
  that.select(values);
});

修改后(无效)的代码

$selectableOptgroup.find('.ms-optgroup-label').on('click', function(){
  var values = $optgroup.children(':not(:selected, :disabled, :hidden)').map(function(){ return $(this).val();}).get();
  that.select(values);
});

插件生成的HTML结构

<div class="ms-container" id="ms-email_contacts">
  <div class="ms-selectable"><input type="text" class="search-input" placeholder="... vyhledávání ...">
    <ul class="ms-list" tabindex="-1">
      <li class="ms-optgroup-container" id="optgroup-selectable--1866734926">
        <ul class="ms-optgroup">
          <li class="ms-optgroup-label" style=""><span>group 1</span></li>
          <li class="ms-elem-selectable" id="1698467390-selectable" style=""><span>a@a.cz (pr-1)</span></li>
          <li class="ms-elem-selectable" id="-181089201-selectable" style=""><span>test@test.cz</span></li>
        </ul>
      </li>
      <li class="ms-optgroup-container" id="optgroup-selectable--1867902347">
        <ul class="ms-optgroup">
          <li class="ms-optgroup-label" style=""><span>Group 2</span></li>
          <li class="ms-elem-selectable" id="-29257990-selectable" style=""><span>a@a.cz (pr-1)</span></li>
          <li class="ms-elem-selectable" id="289161371-selectable" style=""><span>test@test.cz</span></li>
        </ul>
      </li>
    </ul>
  </div>
  <div class="ms-selection"><input type="text" class="search-input" placeholder="... vyhledávání ...">
    <ul class="ms-list" tabindex="-1">
      <li class="ms-optgroup-container" id="optgroup-selection--1866734926">
        <ul class="ms-optgroup">
          <li class="ms-optgroup-label" style="display: none;"><span>group 1</span></li>
          <li class="ms-elem-selection" id="1698467390-selection" style="display: none;"><span>a@a.cz (pr-1)</span></li>
          <li class="ms-elem-selection" id="-181089201-selection" style="display: none;"><span>test@test.cz</span></li>
        </ul>
      </li>
      <li class="ms-optgroup-container" id="optgroup-selection--1867902347">
        <ul class="ms-optgroup">
          <li class="ms-optgroup-label" style="display: none;"><span>Group 2</span></li>
          <li class="ms-elem-selection" id="-29257990-selection" style="display: none;"><span>a@a.cz (pr-1)</span></li>
          <li class="ms-elem-selection" id="289161371-selection" style="display: none;"><span>test@test.cz</span></li>
        </ul>
      </li>
    </ul>
  </div>
</div>

插件初始化函数

function selectMulti(id, search_msg) {
    $('#' + id).multiSelect({
      selectableOptgroup: true,
      keepOrder: true,
      selectableHeader: '<input type="text" class="search-input" placeholder="' + search_msg + '">',
      selectionHeader: '<input type="text" class="search-input" placeholder="' + search_msg + '">',
      afterInit: function(ms) {
        var that = this,
            $selectableSearch = that.$selectableUl.prev(),
            $selectionSearch = that.$selectionUl.prev(),
            selectableSearchString = '#'+that.$container.attr('id')+' li.ms-elem-selectable:not(.ms-selected)',
            selectionSearchString = '#'+that.$container.attr('id')+' li.ms-elem-selection.ms-selected';
        that.qs1 = $selectableSearch.quicksearch(selectableSearchString)
        .on('keydown', function(e){
          if (e.which === 40){
            that.$selectableUl.focus();
            return false;
          }
        });
        that.qs2 = $selectionSearch.quicksearch(selectionSearchString)
        .on('keydown', function(e){
          if (e.which == 40){
            that.$selectionUl.focus();
            return false;
          }
        });
      },
      afterSelect: function() {
        this.qs1.cache();
        this.qs2.cache();
      },
      afterDeselect: function() {
        this.qs1.cache();
        this.qs2.cache();
      }
    });
  }

解决方案

问题出在jQuery的:hidden选择器判断逻辑上,它不仅包含display:none的元素,还包括visibility:hidden、宽高为0等情况,与quicksearch隐藏元素的方式存在判断偏差。直接通过检查元素的display样式筛选可见元素即可解决:

$selectableOptgroup.find('.ms-optgroup-label').on('click', function(){
  var values = $optgroup.children(':not(:selected, :disabled)')
    .filter(function(){
      // 仅保留display不为none的元素
      return $(this).css('display') !== 'none';
    })
    .map(function(){ 
      return $(this).val();
    }).get();
  that.select(values);
});

原理说明

用filter方法手动校验每个元素的display属性,精准筛选出当前可见的选项,避免jQuery伪类选择器的逻辑差异导致的筛选失效问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:58:10