首页 > 解决方案 > jQuery中的多类别过滤器

问题描述

我正在尝试为我的产品列表构建过滤功能。如果选择了一个或多个属性,它应该淡出不匹配的元素。如果一个过滤器被移除,它也应该再次淡入。我认为我的问题是,如果数组不匹配 100%,我没有得到一个真实的陈述。

希望您了解我的问题并帮助我:-)。提前致谢!

$(document).ready(function(){ 
        $('.product-filter ul > li').click(function() {
        
        $(this).find('.level2').slideToggle();
    });
    
    $('.product-list-teaser').each(function() {
        var data = $(this).attr('data-filter'),
            data = data.split(' '),
            data = data.filter(Boolean),
            data = data.sort();
    
    
        $(this).attr('data-filter', data);
        
    
    })
    
    $('.product-filter .level2 li').click(function() {
        var content = $(this).text();
    
        $('.filter').append('<li>' + content + ' <span class="delete"></span></li>');
    
        var contentList = $('.filter li').text(),
            contentList = contentList.split(' '),
            contentList = contentList.filter(Boolean),
            contentList = contentList.sort();

    
        $('.product-list-teaser').each(function() {
    
            if($(this).attr('data-filter') == contentList) {
            
            $(this).fadeIn();;
        }
        else {
            $(this).fadeOut();
        }
    
        })
    
        
    
    });
    
    
    
    $('.filter').on('click', 'li', function() {
        $(this).closest('li').remove();
    })

});
.product-filter { position: relative; z-index: 20; }
.product-filter ul.categories { margin: 0; padding: 0;}
.product-filter ul.categories li { list-style: none; float: left; width: calc(((100% - 220px) / 12) * 4 + (3 * 20px) - 10px); border: solid 5px #e2000a; margin: 0 20px 20px 0; text-align: center; color: #e2000a; font-weight: 700; font-size: 25px; line-height: 30px; cursor: pointer; padding: 17px 0; -webkit-transition: all 0.5s ease-in-out; -moz-transition: all 0.5s ease-in-out; -ms-transition: all 0.5s ease-in-out; -o-transition: all 0.5s ease-in-out; transition: all 0.5s ease-in-out; position: relative;}
.product-filter ul.categories li:after { display: inline-block; width: 13px; height: 12px; background: url('../img/sub-toggle.png') no-repeat 0 0; background-size: 30px; margin-top: 7px; content: ""; margin-left: 10px; background-position: 0 -16px;}
.product-filter ul.categories li:hover { background: #e2000a; color: #fff;}
.product-filter ul.categories li:nth-child(3n+3) { margin-right: 0; }
.product-filter .categories .level2 { display: none; position: absolute; left: -5px; top: 64px; background: #fff; border: solid 5px #e2000a; z-index: 20; border-top: none; width: 100%; margin: 0; padding: 0;}
.product-filter .categories .level2 li { border: none; padding: 10px 0; color: #000; font-size: 18px; line-height: 25px; float: none; margin: 0; font-weight: 300; width: 100%}
.product-filter .categories .level2 li:after { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="product-wrap">
    <div class="product-filter">
        <ul class="categories">
            <li>Category1
                <ul class="level2">
                    <li>aerob</li>
                    <li>anaerob</li>
                </ul>
            </li>
            <li>Category2
                <ul class="level2">
                    <li>industry</li>
                    <li>electronic</li>
                    <li>mechanic</li>
                </ul>
            </li>
            <li>Category3
                <ul class="level2">
                    <li>white</li>
                    <li>blue</li>
                    <li>black</li>
                </ul>
            </li>
        </ul>
        <ul class="filter">
        </ul>
    </div>
    <div class="product-inner-wrap">
        <div class="product-list-teaser" data-filter="aerob industry blue">
            <p>Product aerob industry blue</p>
        </div>
        <div class="product-list-teaser" data-filter="aerob industry white">
            <p>Product aerob industry white</p>
        </div>
    </div>
    </div>

标签: javascriptjqueryfilter

解决方案


我试图尽快做到这一点,但结果有点混乱。有更优雅的方法来实现这一点。我对您的 JS 代码进行了一些修改,但它不能处理删除所有过滤器的情况,您需要重置产品列表。

编辑:includes在数组中搜索以查找给定元素是否存在的函数并非所有浏览器都支持,因为它随 ES7 规范一起提供。您可以在此处检查兼容性

我希望这对你有用!

$(document).ready(function(){ 
        $('.product-filter ul > li').click(function() {
        
        $(this).find('.level2').slideToggle();
    });
    
    
    $('.product-filter .level2 li').click(function() {
        var content = $(this).text();
    
        $('.filter').append('<li>' + content + ' <span class="delete"></span></li>');
    
        var contentList = $('.filter li').text(),
            contentList = contentList.split(' '),
            contentList = contentList.filter(Boolean),
            contentList = contentList.sort();

        $('.product-list-teaser').each(function() {
            var thisProduct = $(this);
            
            var productData = $(this).attr('data-filter'),
            productData = productData.split(' ');
            
            contentList.forEach( function(el) {
              if(productData.includes(el)) {
                  thisProduct.fadeIn();
              }
              else {
                  thisProduct.fadeOut();
              }
            } )
            
         })
    
        
    
    });
    
    
    
    $('.filter').on('click', 'li', function() {
        $(this).closest('li').remove();
    })

});
.product-filter { position: relative; z-index: 20; }
.product-filter ul.categories { margin: 0; padding: 0;}
.product-filter ul.categories li { list-style: none; float: left; width: calc(((100% - 220px) / 12) * 4 + (3 * 20px) - 10px); border: solid 5px #e2000a; margin: 0 20px 20px 0; text-align: center; color: #e2000a; font-weight: 700; font-size: 25px; line-height: 30px; cursor: pointer; padding: 17px 0; -webkit-transition: all 0.5s ease-in-out; -moz-transition: all 0.5s ease-in-out; -ms-transition: all 0.5s ease-in-out; -o-transition: all 0.5s ease-in-out; transition: all 0.5s ease-in-out; position: relative;}
.product-filter ul.categories li:after { display: inline-block; width: 13px; height: 12px; background: url('../img/sub-toggle.png') no-repeat 0 0; background-size: 30px; margin-top: 7px; content: ""; margin-left: 10px; background-position: 0 -16px;}
.product-filter ul.categories li:hover { background: #e2000a; color: #fff;}
.product-filter ul.categories li:nth-child(3n+3) { margin-right: 0; }
.product-filter .categories .level2 { display: none; position: absolute; left: -5px; top: 64px; background: #fff; border: solid 5px #e2000a; z-index: 20; border-top: none; width: 100%; margin: 0; padding: 0;}
.product-filter .categories .level2 li { border: none; padding: 10px 0; color: #000; font-size: 18px; line-height: 25px; float: none; margin: 0; font-weight: 300; width: 100%}
.product-filter .categories .level2 li:after { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="product-wrap">
    <div class="product-filter">
        <ul class="categories">
            <li>Category1
                <ul class="level2">
                    <li>aerob</li>
                    <li>anaerob</li>
                </ul>
            </li>
            <li>Category2
                <ul class="level2">
                    <li>industry</li>
                    <li>electronic</li>
                    <li>mechanic</li>
                </ul>
            </li>
            <li>Category3
                <ul class="level2">
                    <li>white</li>
                    <li>blue</li>
                    <li>black</li>
                </ul>
            </li>
        </ul>
        <ul class="filter">
        </ul>
    </div>
    <div class="product-inner-wrap">
        <div class="product-list-teaser" data-filter="aerob industry blue">
            <p>Product aerob industry blue</p>
        </div>
        <div class="product-list-teaser" data-filter="aerob industry white">
            <p>Product aerob industry white</p>
        </div>
    </div>
    </div>


推荐阅读