jQuery中同时过滤"Radios + Select + Checkbox"的最快方法



在jQuery中过滤不同类型过滤器组合的最快策略(就性能而言)是什么?

在这个例子中;无线电+选择+复选框";并且需要它们同时一起操作。

JS Bin链接:https://jsbin.com/wegopom/3/edit?js,输出

我在基于的传单地图中瞄准<img>标记

  • 图像的";src"> 例如img[src$="marker-icon.png"](以文件名结尾)
  • 图像的";类"> 例如img.variation

过滤器的速度是核心,因为此地图将显示数百甚至数千个标记图像。


对于无线电,("变体"类)。。。我有一个更改功能:

jQuery(document).on("change", ".variation", function() {

对于Select,("filterballer"ID)。。。我有第二个更改功能:

jQuery('#filterbottler').change(function(){

对于复选框,("中断"ID)。。。我有第三个更改功能:

jQuery('#outages').change(function(){

使用一堆IF语句和邻接/链接类(比如img.variation.buller,这会非常慢),让其中两个更改函数协同工作很简单。。。但现在我添加了第三个过滤器,这似乎是过载,现在我很难把我的大脑包裹在每一个过滤场景中。

JS Bin@https://jsbin.com/wegopom/3/edit?js,输出功能这三个滤波器中的每一个都独立工作。。。

目标是让前三个过滤器(Variation、Bottler和Outages)以最快、最有效的方式同时工作。我该如何解决此问题?


jQuery(document).ready(function($){
// Filter 1) by Variation
jQuery(document).on("change", ".variation", function() {
var bottlerValue = jQuery("#filterbottler").find("option:selected").val();
var bottlerClass = '.field-ccb-cached__'+bottlerValue;
// marker groups to be used in exclusionary :not() statements so they aren't affected by the filters... e.g. marker-icon.png & marker-icon-2x.png are "My Location" markers
var mainMarkers = '[src$="bottler_22px.png"],[src$="marker-icon.png"],[src$="marker-icon-2x.png"]';
var includeOutageMarkers = '[src$="bottler_22px.png"],[src$="marker-icon.png"],[src$="marker-icon-2x.png"],[src$="cross_22px.png"]';
if (this.id == "map-filters-show-all") {
jQuery('.leaflet-marker-pane img:not('+mainMarkers+')').show(500);
}
else if (this.id == "map-filters-16oz-cans") {
jQuery('.leaflet-marker-pane img:not('+includeOutageMarkers+',.field-report-variation__16oz-cans)').hide(500);
jQuery('.leaflet-marker-pane img.field-report-variation__16oz-cans').show(500);
} else if (this.id == "map-filters-12oz-cans") {
jQuery('.leaflet-marker-pane img:not('+includeOutageMarkers+',.field-report-variation__12oz-cans)').hide(500);
jQuery('.leaflet-marker-pane img.field-report-variation__12oz-cans').show(500);
} else if (this.id == "map-filters-fountain-surge") {
jQuery('.leaflet-marker-pane img:not('+includeOutageMarkers+',.field-report-variation__fountain-surge)').hide(500);
jQuery('.leaflet-marker-pane img.field-report-variation__fountain-surge').show(500);
} else if (this.id == "map-filters-fountain-surge-red-berry-blast") {
jQuery('.leaflet-marker-pane img:not('+includeOutageMarkers+',.field-report-variation__fountain-surge-red-berry-blast)').hide(500);
jQuery('.leaflet-marker-pane img.field-report-variation__fountain-surge-red-berry-blast').show(500);
}
});
// Filter 2) by Bottling Company (select box)
jQuery('#filterbottler').change(function(){
var bottlerValue = jQuery("#filterbottler").find("option:selected").val();
var bottlerClass = '.field-ccb-cached__'+bottlerValue;
if (bottlerClass != '.field-ccb-cached___none') {
jQuery('.leaflet-marker-pane img:not([src$="bottler_22px.png"],[src$="marker-icon.png"],[src$="marker-icon-2x.png"],[src$="cross_22px.png"],'+bottlerClass+')').hide(500);
jQuery('.leaflet-marker-pane img'+bottlerClass).show(500);
}
if (bottlerClass === '.field-ccb-cached___none') {
jQuery('.leaflet-marker-pane img:not([src$="bottler_22px.png"],[src$="marker-icon.png"],[src$="marker-icon-2x.png"])').show(500);
}
});
// Filter 3) Show Outage Reports (checkbox on/off)
jQuery('#outages').change(function(){
if(this.checked){
jQuery('.leaflet-marker-pane img[src$="cross_22px.png"],[src$="exclamation_22px.png"]').fadeToggle(500);
jQuery.cookie('outagemarkers', true);
}
else {
jQuery('.leaflet-marker-pane img[src$="cross_22px.png"],[src$="exclamation_22px.png"]').fadeToggle(500);
jQuery.cookie('outagemarkers', false);
}
});

更新

  1. 我已经更新了jQuery和纯JS解决方案,将所有常量变量移到事件处理程序之外,以提高性能
  2. 我改进了为两者构建选择器和过滤器的方式。对于jQuery,这意味着当过滤器未激活(设置为show-allnone)时,使用'*'作为后备vaklue。在纯JS中,我使用布尔false来";关闭";过滤器,然后当稍后使用filter()时,如果过滤器设置为false,我手动将过滤器条件设置为true以绕过它
  3. 我们查询的一些选择器可以简化。例如,我不是查询所有的选择选项,然后使用find()filter()来查找selected,只获取该选项的值,而是简单地获取<select>元素本身的值。在jQuery:bottlerSelect.val()中,在纯JS:bottlerSelect.value

为了最大限度地提高程序的性能,最好将所有过滤器放在一个块中,然后对所有过滤器进行过滤。一旦我们定义了所有想要的过滤器,我们就可以通过过滤器选择器过滤所有标记,并将它们保存到matchedMarkers变量中。然后,我们可以将不匹配的内容保存到一个单独的unmatchedMarkers中,其中有一行:unmatchedMarkers = allMarkers.not(matchedMarkers);

总之,它实际上是一个非常简单和轻量级的程序,而且它在香草JS中可能会更高效,我希望在未来一两天内重新访问它。

jQuery解决方案

CodePen链接:https://cdpn.io/e/943560466fc36d61871d01b57739137d

jQuery(document).ready(function($){
var allMarkers = $('.leaflet-marker-icon'),
variationPrefix = 'field-report-variation__',
bottlerPrefix = 'field-ccb-cached__',
outagesSelector = ':not([src$="cross_22px.png"],[src$="exclamation_22px.png"])',
variationInputs = $('input.variation'),
bottlerSelect = $('#filterbottler'),
outagesCheckbox = $('#outages');
$(document).on('change', '.variation, #filterbottler, #outages', function() {
var variationSelector = '.'+variationPrefix+variationInputs.filter(':checked').attr('id').split('-').slice(2).join('-').toLowerCase().replace(/ /g,'-'),
variationFilter = variationSelector.endsWith('__show-all') ? '*' : variationSelector + ',:not([class*="'+variationPrefix+'"])',
bottlerSelector = '.'+bottlerPrefix+bottlerSelect.val(),
bottlerFilter = bottlerSelector.endsWith('___none') ? '*' : bottlerSelector + ',:not([class*="'+bottlerPrefix+'"])',
outagesFilter = outagesCheckbox.is(':checked') ? '*' : outagesSelector,
matchedMarkers = allMarkers.filter(variationFilter).filter(bottlerFilter).filter(outagesFilter),
unmatchedMarkers = allMarkers.not(matchedMarkers);
matchedMarkers.fadeIn(500);
unmatchedMarkers.fadeOut(500);
});
});
.leaflet-marker-pane{width:100%;border:1px solid #000}table td{min-width:25px;height:30px;border:1px solid gray;padding:10px}
<div class="form-item" id="map-filter-content"> <label style="font-size:18px;">Filter Reports by Variation <i>(must either "Show All" or be a specific variation):</i></label><div class="form-checkboxes"> <input type="radio" value="Show All" name="variation" class="variation" id="map-filters-show-all" checked=""> <label>Show All</label><br> <input type="radio" value="16oz Cans" name="variation" class="variation" id="map-filters-16oz-cans"> <label>16oz Cans</label><br> <input type="radio" value="12oz Cans" name="variation" class="variation" id="map-filters-12oz-cans"> <label>12oz Cans</label><br> <input type="radio" value="Fountain SURGE" name="variation" class="variation" id="map-filters-fountain-surge"> <label>Fountain SURGE</label><br> <input type="radio" value="Fountain SURGE Red Berry Blast" name="variation" class="variation" id="map-filters-fountain-surge-red-berry-blast"> <label>Fountain SURGE Red Berry Blast</label></div><hr style="margin:15px 0 10px 0;"><div class="field-widget-options-select form-wrapper"><div class="control-group form-type-select form-item"> <label style="font-size:18px;">Filter by Bottling Company <i>(must either "Show All" or be a specific bottler):</i></label><div class="controls"> <select id="filterbottler" class="form-select"><option value="_none">- Select All Coca-Cola Bottlers -</option><option value="190">ABARTA</option><option value="191">Aberdeen Coca-Cola</option><option value="192">Ada Coca-Cola</option><option value="193">Atlantic Coca-Cola</option><option value="194">Bemidji Coca-Cola</option><option value="195">Binks Coca-Cola</option><option value="196">Canyon City Coca-Cola</option><option value="197">Cedar City Coca-Cola</option><option value="198">Chesterman Coca-Cola</option><option value="199">Clark</option><option value="200">Coca-Cola Consolidated</option><option value="186">Coca-Cola High Country</option><option value="187">Coca-Cola Southwest</option><option value="177">Coca-Cola UNITED</option><option value="201">Columbus Coca-Cola</option><option value="202">Corinth</option><option value="203">Decatur</option><option value="204">Deming Coca-Cola</option><option value="205">Dickinson Coca-Cola</option><option value="206">Durango Coca-Cola</option><option value="207">Durham Coca-Cola</option><option value="183">Emporia Coca-Cola</option><option value="208">Florida Coca-Cola</option><option value="209">Fort Smith Coca-Cola</option><option value="244">Glasgow Coca-Cola</option><option value="210">Glendive Coca-Cola</option><option value="211">Great Lakes Coca-Cola</option><option value="212">Hancock</option><option value="213">Heartland Coca-Cola</option><option value="214">Hot Springs Coca-Cola</option><option value="215">Huntsville</option><option value="216">Idabel Coca-Cola</option><option value="217">Internation Falls</option><option value="218">Jefferson Coca-Cola</option><option value="219">Ketchikan</option><option value="220">Kokomo Coca-Cola</option><option value="178">Lehrkinds</option><option value="184">Liberty Coca-Cola</option><option value="221">Love Coca-Cola</option><option value="222">Lufkin Coca-Cola</option><option value="223">Macon</option><option value="224">Magnolia Coca-Cola</option><option value="225">Maui</option><option value="226">Meridian</option><option value="227">MiddlesBoro</option><option value="179">Mile High</option><option value="228">Minden Coca-Cola</option><option value="182">Nashville Coca-Cola</option><option value="229">Northern New England</option><option value="230">ODOM</option><option value="231">Orangeburg Coca-Cola</option><option value="232">Ozarks Coca-Cola</option><option value="233">Pulaski Coca-Cola</option><option value="176">Reyes Coca-Cola</option><option value="234">Rock Hill Coca-Cola</option><option value="235">Santa Fe Coca-Cola</option><option value="236">Sitka</option><option value="237">Sooner Coca-Cola</option><option value="185">Swire Coca-Cola</option><option value="181">Timber Country</option><option value="238">Trenton Coca-Cola</option><option value="180">Tullahoma Coca-Cola</option><option value="239">Union City</option><option value="174">Viking Coca-Cola</option><option value="240">Washington Coca-Cola</option><option value="241">Williston Coca-Cola</option><option value="188">Winfield Coca-Cola</option><option value="242">Winona Coca-Cola</option><option value="243">Yakima Coca-Cola</option> </select></div></div></div><hr style="margin:15px 0 10px 0;"><div class="mwcheck"> <input type="checkbox" id="outages" checked> <label>Show Outage Reports <i>(must turn these icons on/off with other filters intact: <img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png"> & <img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/cross_22px.png">)</i></label></div></div><hr><div class="leaflet-marker-pane"><table><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/cross_22px.png" class="leaflet-marker-icon tag-inside-marker field-ccb-cached__191"></td><td> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b> <br><br>This always shows unless:<br>1) "Show Outage Reports" is deselected... or <br>2) Another bottling company (e.g. ABARTA is selected)<br></td></tr></table></div>
<script src="https://code.jquery.com/jquery-1.8.3.js"></script>

纯JavaScript解决方案

CodePen链接:https://cdpn.io/e/d9e89a278a7bb190841c19f53c376033

这个纯香草的JavaScript解决方案甚至比jQuery解决方案更简单,如果您可以将jQuery完全排除在这个项目之外,并坚持使用纯JS,它将大大提高性能。无需等待页面完全加载。只需在HTML内容之后立即运行JavaScript,一切都会按预期进行。这也为我们的过滤方法提供了更大的灵活性。我们可以在一个过滤器方法中运行所有条件,并立即淡入或淡出相关的标记元素,而不是背靠背运行三个过滤器函数。同样为了提高性能,我在CSS中创建了两个简单的状态,即默认状态(opacity: 1)和由类.filtered表示的过滤状态,而不是依赖JavaScript来动画化渐变。所有的淡入和淡出都在CSS中完成,通过是否应用.filtered类来确定简单的CSS转换。

这里是纯JavaScript:

const allMarkers = Array.from(document.querySelectorAll('.leaflet-marker-icon')),
variationPrefix = 'field-report-variation__',
bottlerPrefix = 'field-ccb-cached__',
outagesSelector = ':not([src$="cross_22px.png"],[src$="exclamation_22px.png"])',
variationInputs = Array.from(document.querySelectorAll('input.variation')),
bottlerSelect = document.getElementById('filterbottler'),
outagesCheckbox = document.getElementById('outages');
document.addEventListener('change', e => {
if (e.target?.matches('.variation, #filterbottler, #outages')) {
const variationSelector = '.'+variationPrefix+variationInputs.filter(input => input.checked)[0].id.split('-').slice(2).join('-').toLowerCase().replace(/ /g,'-'),
variationFilter = variationSelector.endsWith('__show-all') ? false : variationSelector + ',:not([class*="'+variationPrefix+'"])',
bottlerSelector = '.'+bottlerPrefix+bottlerSelect.value,
bottlerFilter = bottlerSelector.endsWith('___none') ? false : bottlerSelector + ',:not([class*="'+bottlerPrefix+'"])',
outagesFilter = outagesCheckbox.checked ? false : outagesSelector;
allMarkers.forEach(marker => ((variationFilter ? marker.matches(variationFilter) : true) && (bottlerFilter ? marker.matches(bottlerFilter) : true) && (outagesFilter ? marker.matches(outagesFilter) : true)) ? marker.classList.remove('filtered') : marker.classList.add('filtered'));
}
});
.leaflet-marker-pane{width:100%;border:1px solid #000}table td{min-width:25px;height:30px;border:1px solid gray;padding:10px}
.leaflet-marker-icon {
opacity: 1;
transition: opacity 500ms ease-out;
}
.leaflet-marker-icon.filtered {
opacity: 0;
}
<div class="form-item" id="map-filter-content"> <label style="font-size:18px;">Filter Reports by Variation <i>(must either "Show All" or be a specific variation):</i></label><div class="form-checkboxes"> <input type="radio" value="Show All" name="variation" class="variation" id="map-filters-show-all" checked=""> <label>Show All</label><br> <input type="radio" value="16oz Cans" name="variation" class="variation" id="map-filters-16oz-cans"> <label>16oz Cans</label><br> <input type="radio" value="12oz Cans" name="variation" class="variation" id="map-filters-12oz-cans"> <label>12oz Cans</label><br> <input type="radio" value="Fountain SURGE" name="variation" class="variation" id="map-filters-fountain-surge"> <label>Fountain SURGE</label><br> <input type="radio" value="Fountain SURGE Red Berry Blast" name="variation" class="variation" id="map-filters-fountain-surge-red-berry-blast"> <label>Fountain SURGE Red Berry Blast</label></div><hr style="margin:15px 0 10px 0;"><div class="field-widget-options-select form-wrapper"><div class="control-group form-type-select form-item"> <label style="font-size:18px;">Filter by Bottling Company <i>(must either "Show All" or be a specific bottler):</i></label><div class="controls"> <select id="filterbottler" class="form-select"><option value="_none">- Select All Coca-Cola Bottlers -</option><option value="190">ABARTA</option><option value="191">Aberdeen Coca-Cola</option><option value="192">Ada Coca-Cola</option><option value="193">Atlantic Coca-Cola</option><option value="194">Bemidji Coca-Cola</option><option value="195">Binks Coca-Cola</option><option value="196">Canyon City Coca-Cola</option><option value="197">Cedar City Coca-Cola</option><option value="198">Chesterman Coca-Cola</option><option value="199">Clark</option><option value="200">Coca-Cola Consolidated</option><option value="186">Coca-Cola High Country</option><option value="187">Coca-Cola Southwest</option><option value="177">Coca-Cola UNITED</option><option value="201">Columbus Coca-Cola</option><option value="202">Corinth</option><option value="203">Decatur</option><option value="204">Deming Coca-Cola</option><option value="205">Dickinson Coca-Cola</option><option value="206">Durango Coca-Cola</option><option value="207">Durham Coca-Cola</option><option value="183">Emporia Coca-Cola</option><option value="208">Florida Coca-Cola</option><option value="209">Fort Smith Coca-Cola</option><option value="244">Glasgow Coca-Cola</option><option value="210">Glendive Coca-Cola</option><option value="211">Great Lakes Coca-Cola</option><option value="212">Hancock</option><option value="213">Heartland Coca-Cola</option><option value="214">Hot Springs Coca-Cola</option><option value="215">Huntsville</option><option value="216">Idabel Coca-Cola</option><option value="217">Internation Falls</option><option value="218">Jefferson Coca-Cola</option><option value="219">Ketchikan</option><option value="220">Kokomo Coca-Cola</option><option value="178">Lehrkinds</option><option value="184">Liberty Coca-Cola</option><option value="221">Love Coca-Cola</option><option value="222">Lufkin Coca-Cola</option><option value="223">Macon</option><option value="224">Magnolia Coca-Cola</option><option value="225">Maui</option><option value="226">Meridian</option><option value="227">MiddlesBoro</option><option value="179">Mile High</option><option value="228">Minden Coca-Cola</option><option value="182">Nashville Coca-Cola</option><option value="229">Northern New England</option><option value="230">ODOM</option><option value="231">Orangeburg Coca-Cola</option><option value="232">Ozarks Coca-Cola</option><option value="233">Pulaski Coca-Cola</option><option value="176">Reyes Coca-Cola</option><option value="234">Rock Hill Coca-Cola</option><option value="235">Santa Fe Coca-Cola</option><option value="236">Sitka</option><option value="237">Sooner Coca-Cola</option><option value="185">Swire Coca-Cola</option><option value="181">Timber Country</option><option value="238">Trenton Coca-Cola</option><option value="180">Tullahoma Coca-Cola</option><option value="239">Union City</option><option value="174">Viking Coca-Cola</option><option value="240">Washington Coca-Cola</option><option value="241">Williston Coca-Cola</option><option value="188">Winfield Coca-Cola</option><option value="242">Winona Coca-Cola</option><option value="243">Yakima Coca-Cola</option> </select></div></div></div><hr style="margin:15px 0 10px 0;"><div class="mwcheck"> <input type="checkbox" id="outages" checked> <label>Show Outage Reports <i>(must turn these icons on/off with other filters intact: <img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png"> & <img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/cross_22px.png">)</i></label></div></div><hr><div class="leaflet-marker-pane"><table><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__190"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__190" <b>("ABARTA Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__16oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__16oz-cans" <b>(16oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" class="leaflet-marker-icon tag-inside-marker field-report-variation__12oz-cans field-ccb-cached__191"></td><td> < Has Class "field-report-variation__12oz-cans" <b>(12oz Cans)</b><br> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b></td></tr><tr><td><img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/cross_22px.png" class="leaflet-marker-icon tag-inside-marker field-ccb-cached__191"></td><td> < Has Class "field-ccb-cached__191" <b>("Aberdeen Coca-Cola" Bottling Company)</b> <br><br>This always shows unless:<br>1) "Show Outage Reports" is deselected... or <br>2) Another bottling company (e.g. ABARTA is selected)<br></td></tr></table></div>

过滤jQuery中不同类型过滤器的组合?

我认为可以肯定地说,条件越少,选择器越少,性能就越好(尽管如果没有基准测试,我们实际上无法知道)。

为了实现这个目标,您只能使用类。

以下代码基于您的jsbin,其行为方式如下:

  1. 它引入了三个新类:variationbottleroutage
  2. 它使用过滤器控制器值作为类名称部分(例如,使用装瓶器的值190来选择类bottler-190)
  3. 当选择了两个或多个过滤器(例如,变体和装瓶器)时,应显示这些过滤器的交集。
    • 这是一个重要的问题。在某些情况下,当前代码有缺陷的原因是,您在自己的处理程序上分别处理每个过滤器,而实际上,在任何change事件上,您必须始终考虑所有现有的过滤器
  4. 它更改和缩短了现有的类名,以方便、更好的可读性和更容易的维护。
    • 例如,field-report-variation__12oz-cans被替换为"variation-12oz">
  5. 为了提高这个答案的可读性,我自由删除了:
    a。未使用的类(例如tag-inside-marker)
    b。未使用的元素(例如Fountain SURGE单选按钮)
    当然,它们可以直接退回并根据需要使用

让我先向您展示代码,然后我将列出一些注释和假设:

$(document).ready(function () {
$('.variation, #bottler, #outage').change(function () {
filter();
});
});
const baseSelector = ".leaflet-marker-icon";
function filter() {
// controllers values
const variation = $('input[name="variation"]:checked')[0].id;
const bottler = $('#bottler').val();
const outage = $('#outage').is(':checked'); 
// selectors to show
let variationSelector = variation.includes('all') ? '.variation' : '.' + variation;
let bottlerSelector = bottler.includes('all') ? '.bottler' : '.bottler-' + bottler;
let outageSelector = outage ? '.outage' : '' ;
// show
$(`${baseSelector}${variationSelector}${bottlerSelector}
${outageSelector ? ',' + baseSelector + outageSelector : ''}`).fadeIn(500);
// selectors to hide
variationSelector = variationSelector == '.variation' ? '' : variationSelector;
bottlerSelector = bottlerSelector == '.bottler' ? '' : bottlerSelector;
outageSelector = outage ? '' : '.outage'; 
const any = bottlerSelector || variationSelector;
// hide
$(`${ any ? `${baseSelector}:not(${[bottlerSelector,variationSelector].filter(n => n).join('')})` : '' }
${outageSelector ? (any ? ',' : '') + baseSelector + outageSelector : ''}`).fadeOut(500);
}
table td {
min-width:25px;
height:30px;
border:1px solid gray;
padding:10px;
}
.leaflet-marker-pane {
width:200px
height:200px;
border:1px solid black;
}
<script src="https://code.jquery.com/jquery-1.8.3.js"></script>
<div class="form-item" id="map-filter-content">
<label style="font-size:18px;">Filter Reports by Variation <i>(must either "Show All" or be a specific variation):</i></label>
<div class="form-checkboxes">
<input id="variation-all" type="radio" value="Show All" name="variation" class="variation" checked="">
<label>Show All</label><br>
<input id="variation-16oz" type="radio" value="16oz Cans" name="variation" class="variation">
<label>16oz Cans</label><br>
<input id="variation-12oz" type="radio" value="12oz Cans" name="variation" class="variation">
<label>12oz Cans</label><br>
</div>
<hr style="margin:15px 0 10px 0;">
<div class="field-widget-options-select form-wrapper">
<div class="control-group form-type-select form-item">
<label style="font-size:18px;">Filter by Bottling Company <i>(must either "Show All" or be a specific bottler):</i></label>
<div class="controls">
<select id="bottler" class="form-select">
<option value="all">- Select All Coca-Cola Bottlers -</option>
<option value="190">ABARTA</option>
<option value="191">Aberdeen Coca-Cola</option>
</select>
</div>
</div>
</div>
<hr style="margin:15px 0 10px 0;">
<div class="mwcheck">
<input type="checkbox" id="outage" checked>
<label>Show Outage Reports <i>(must turn these icons on/off with other filters intact: <img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png"> & <img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/cross_22px.png">)</i></label></div>
</div>
<hr>
<div class="leaflet-marker-pane">
<table>
<tr>
<td>
<img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" 
class="leaflet-marker-icon variation variation-16oz bottler bottler-190">
</td>
<td>
Has class "variation-16oz" <b>(16oz Cans)</b><br>
Has class "bottler-190" <b>("ABARTA" Bottling Company)</b>
</td>
</tr>
<tr>
<td>
<img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" 
class="leaflet-marker-icon variation variation-12oz bottler bottler-190">
</td>
<td>
Has class "variation-12oz" <b>(12oz Cans)</b><br>
Has class "bottler-190" <b>("ABARTA" Bottling Company)</b>
</td>
</tr>
<tr>
<td>
<img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/check_22px.png" 
class="leaflet-marker-icon variation variation-12oz bottler bottler-191">
</td>
<td>
Has Class "variation-12oz" <b>(12oz Cans)</b><br>
Has class "bottler-191" <b>("Aberdeen Coca-Cola")</b>
</td>
</tr>
<tr>
<td>
<img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" 
class="leaflet-marker-icon variation variation-16oz bottler bottler-190 outage">
</td>
<td>
Has class "variation-16oz" <b>(16oz Cans)</b><br>
Has class "bottler-190" <b>("ABARTA" Bottling Company)</b>
</td>
</tr>
<tr>
<td>
<img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" 
class="leaflet-marker-icon variation variation-16oz bottler bottler-191 outage">
</td>
<td>
Has class "variation-16oz" <b>(16oz Cans)</b><br>
Has class "bottler-191" <b>("Aberdeen Coca-Cola")</b>
</td>
</tr>
<tr>
<td>
<img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/exclamation_22px.png" 
class="leaflet-marker-icon variation variation-12oz bottler bottler-191 outage">
</td>
<td>
Has Class "variation-12oz" <b>(12oz Cans)</b><br>
Has Class "bottler-191" <b>("Aberdeen Coca-Cola")</b>
</td>
</tr>
<tr>
<td>
<img src="https://surgemovement.org/sites/all/themes/surgemovement/images/ip_geoloc_custom_markers/cross_22px.png" 
class="leaflet-marker-icon variation variation-16oz variation-12oz bottler bottler-191 outage"></td>
<td>
Has Class "bottler-191" <b>("Aberdeen Coca-Cola")</b>
<br><br>
This always shows unless:<br>
1) "Show Outage Reports" is deselected <br>
2) Another bottling company (e.g. ABARTA is selected)<br>
</td>
</tr>
</table>
</div>

我将为您提供一些规则,这些规则可以帮助您以最佳方式优化性能,因为每个问题都有自己的解决方案。

1.事件侦听器提高事件侦听器性能的最佳方法是使用委派,对于如此多的筛选器触发器,我建议您将它们全部封装在一个父项下,并根据触发子项触发更改

你可以在这里阅读更多

示例:

// Attach a delegated event handler with a more refined selector
$( "#list" ).on( "click", "a[href^='http']", function( event ) {
$( this ).attr( "target", "_blank" );
});

2.动画

我看到您正在使用jQueryshowhide,为了获得最佳性能,您可能需要阅读本文,特别是基准测试部分。

要想看到真正的差异,请尝试使用大量的点。

结论可能是,仅仅添加和删除一个类(具有转换)就比使用jQuery动画快得多


3.选择器当您在大量dom元素上运行此程序时,这是最有效的部分,对此您可以参考本文或问题


4.实现使用类来描述数据字段可能不是最好的主意。类用于决定事物应该如何绘制、看起来像什么或设置动画。。等等,但不是例如定义产品是可口可乐还是百事可乐。。车辆或椅子。

因此,请尝试使用数据属性(在jQuery:data中)

这不仅会使代码更具可读性,还会使逻辑更易于编写,选择器更具性能。


最后的想法:基准测试始终是判断事物如何运行的最佳方式,您可以始终使用:

  • JSbenchme
  • JSBen.ch

不幸的是,最好的jsperf已经不可用了,但这些应该可以完成任务。

最新更新