在 jQuery 中同时过滤“Radios + Select + Checkbox”的最快方法

Web*_*bMW 8 javascript jquery

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

在这个例子中,我使用“Radios + Select + Checkbox”并需要它们同时操作。

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

<img>在基于以下内容的传单地图中定位标记:

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

过滤器的速度是核心,因为这张地图将显示成百上千的标记图像。


对于收音机,(“变体”类)...我有一个更改功能:

jQuery(document).on("change", ".variation", function() {
Run Code Online (Sandbox Code Playgroud)

对于选择,(“filterbottler”ID)...我有第二个更改功能:

jQuery('#filterbottler').change(function(){
Run Code Online (Sandbox Code Playgroud)

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

jQuery('#outages').change(function(){
Run Code Online (Sandbox Code Playgroud)

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

JS Bin @ https://jsbin.com/wego/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);
        }
    });
Run Code Online (Sandbox Code Playgroud)

Bra*_*ell 2

更新

  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);
  });
});
Run Code Online (Sandbox Code Playgroud)
.leaflet-marker-pane{width:100%;border:1px solid #000}table td{min-width:25px;height:30px;border:1px solid gray;padding:10px}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

纯 JavaScript 解决方案

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

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

这是纯 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'));
  }
});
Run Code Online (Sandbox Code Playgroud)
.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;
}
Run Code Online (Sandbox Code Playgroud)
<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 C


Copyright Info

© Copyright 2013-2021 admin@qa.1r1g.com

如未特别说明,本网站的内容使用如下协议:
Creative Commons Atution-NonCommercial-ShareAlike 4.0 International license
.

用以下方式浏览
回到顶部