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
相关产品推荐
相关产品推荐

