如何使用jQuery选择性地显示和隐藏元素

时间:2018-03-19 18:10:24

标签: jquery

首先请原谅我要转储的代码量。

当前行为:当您单击li时,将data-id放入或移出数组,并显示包含数组中的类的表行,并且所有其他表行都是隐。目的是从表中过滤掉与用户选择不匹配的行。

问题:如果我选择了位置"戛纳"从ul.location然后我选择" Villa"和"酒店"从ul.propertytype我可能最终会在表格中显示不是neceserilly别墅和戛纳酒店的行,我将获得戛纳的别墅和酒店以及包含别墅,酒店或戛纳类别的任何其他属性行。

所需行为:我希望能够在戛纳看到别墅和酒店。或者,例如,如果我选择"戛纳"和" Eze"从地点和"别墅"和"酒店"从propertytypes,我只想看戛纳和Eze的别墅和酒店

我玩过:可见的选择器和foreach循环等,但这有点超出我的范围。

以下是我的过滤器 还有3个其他过滤器,但为了保持简单,我只包括2个,其他的没有代码差异。

地点(实时代码中超过30个)

<ul class="location" multiple="">                   
    <li data-id="term_87" class="">Cannes</li>
    <li data-id="term_88">Cap d'Antibes &amp; Juan les Pins</li>
    <li data-id="term_133" class="">Eze</li>
</ul>

属性类型(实时代码中有超过30个)

<ul class="propertytype others" multiple="">                    
    <li data-id="villa">Villa</li>      
    <li data-id="hotel">Hotel</li>                  
    <li data-id="hotelVillas">Hotel Villas</li> 
</ul>

属性行表 Super Simplified(实时代码中超过1200)

<table class="elegant_list_properties">
 <tr id="1" class="propertyrow cannes villa">
    <td>some stuff</td>
 </tr>
 <tr id="2" class="propertyrow cannes hotel">
    <td>some stuff</td>
 </tr>
 <tr id="3" class="propertyrow eze villa">
    <td>some stuff</td>
 </tr>
 <tr id="4" class="propertyrow london villa">
    <td>some stuff</td>
 </tr>
 <tr id="5" class="propertyrow paris hotel">
    <td>some stuff</td>
 </tr>
</table>

示例情况和所需行为

如果我点击&#34;戛纳&#34;和&#34; Eze&#34;地点(ul.locations),我点击&#34;别墅&#34;和&#34;酒店&#34;属性类型(ul.propertytype),我应该只看到tr#1,tr#2和tr#3。

请参阅下面我正在使用的剧本并使用。

打墙
//For the location filters
jQuery('.elegant_filters ul li').on('click', function(e){
    jQuery(this).toggleClass('selected');
    var filters = [];
    jQuery('.elegant_filters ul li.selected').each(function(){
        var val = jQuery(this).attr('data-id');
        filters.push('.'+val);          
    });
    console.log(filters);
    if (jQuery(filters).length < 1) {
        jQuery('.elegant_list_properties tr.propertyrow').show();
    } else {
        jQuery('.elegant_list_properties tr.propertyrow').hide();
        jQuery(filters.join(', ')).show();          
    }    
})

2 个答案:

答案 0 :(得分:1)

您可以使用类,而不是 data-id 。第一类组与位置相关,而第二类与其他相关。 获取所选元素可以创建两个选择器组:第一个用于获取具有这些类的所有元素。第二个是为了过滤具有属于第二组的类的元素:

jQuery('.elegant_filters ul li').on('click', function (e) {
    jQuery(this).toggleClass('selected');
    var filtersLocation = [];
    var filtersOthers = [];
    jQuery('.elegant_filters ul.location li.selected').each(function () {
        var val = this.textContent.toLowerCase().replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, "\\$1");
        filtersLocation.push('.' + val);
    });
    jQuery('.elegant_filters ul.others li.selected').each(function () {
        var val = this.textContent.toLowerCase().replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, "\\$1");
        filtersOthers.push('.' + val);
    });
    jQuery('.elegant_list_properties tr.propertyrow')
            .hide()
            .filter(filtersLocation.length > 0 ? filtersLocation.join(', ') : '*')
            .filter(filtersOthers.length > 0 ? filtersOthers.join(', ') : '*').show();
})
.selected {
    background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div class="elegant_filters">
    <ul class="location" multiple="">
        <li data-id="term_87" class="">Cannes</li>
        <li data-id="term_88">Cap d'Antibes &amp; Juan les Pins</li>
        <li data-id="term_133" class="">Eze</li>
    </ul>
    <ul class="propertytype others" multiple="">
        <li data-id="villa">Villa</li>
        <li data-id="hotel">Hotel</li>
        <li data-id="hotelVillas">Hotel Villas</li>
    </ul>
</div>
<table class="elegant_list_properties">
    <tr id="1" class="propertyrow cannes villa">
        <td>....propertyrow cannes villa....</td>
    </tr>
    <tr id="2" class="propertyrow cannes hotel">
        <td>...propertyrow cannes hotel...</td>
    </tr>
    <tr id="3" class="propertyrow eze villa">
        <td>...propertyrow eze villa....</td>
    </tr>
    <tr id="4" class="propertyrow london villa">
        <td>....propertyrow london villa...</td>
    </tr>
    <tr id="5" class="propertyrow paris hotel">
        <td>....propertyrow paris hotel...</td>
    </tr>
</table>

答案 1 :(得分:0)

您可以创建两个组(一个用于locations,另一个用于prototype others)并搜索data-id类中的每个<tr>(如果locations },文本)。

$('.location li, .propertytype li').on('click', function(e){
    $(this).toggleClass("selected"); //toggle the class selected, easy way to 'turn it on/off'
    showTbInfo(); //go to the function to show <tr>
});

function showTbInfo(){
    //arrays of the two <li>
    let locations = [], properties = [];
    
    //loop through <li> with .selected
    $('.location, .propertytype').find('.selected').each(function(e){
    
        //check if the <li> has .location
        if($(this).parent().hasClass('location')){ 
        
            //get the first word of tag text, in lower case
            let text = ($(this).text().indexOf(" ") > 0 ? $(this).text().substring(0, $(this).text().indexOf(" ")) : $(this).text()).toLowerCase();
            
            //add the word to locations array
            locations.push("." + text);
            
        //check if the <li> has .propertytype
        }else if($(this).parent().hasClass('propertytype')){
        
            //get the data-id attribute
            properties.push("." + $(this).data('id'));
        }
    });
  
    //if the arrays are empty, show everything
    if(locations.length <= 0 && properties.length <= 0){
        $('.elegant_list_properties tr').show();
    }else{
        //start hiding everything
        $('.elegant_list_properties tr').hide();
        
        //show every location. Example: $('.cannes, .eze').show();
        if(locations.length > 0){
            $(locations.join(", ")).show();
        }
        
        //hide every shown element that is visible but doesn't have any of the properties in .propertytype
        if(properties.length > 0){
          $('.elegant_list_properties tr:visible:not(' + properties.join(", ") + ')').hide();
        }
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul class="location" multiple="">                   
    <li data-id="term_87" class="">Cannes</li>
    <li data-id="term_88">Cap d'Antibes &amp; Juan les Pins</li>
    <li data-id="term_133" class="">Eze</li>
</ul>

<ul class="propertytype others" multiple="">                    
    <li data-id="villa">Villa</li>      
    <li data-id="hotel">Hotel</li>                  
    <li data-id="hotelVillas">Hotel Villas</li> 
</ul>

<table class="elegant_list_properties">
 <tr id="1" class="propertyrow cannes villa">
    <td>cannes villa</td>
 </tr>
 <tr id="2" class="propertyrow cannes hotel">
    <td>cannes hotel</td>
 </tr>
 <tr id="3" class="propertyrow eze villa">
    <td>eze villa</td>
 </tr>
 <tr id="4" class="propertyrow london villa">
    <td>london villa</td>
 </tr>
 <tr id="5" class="propertyrow paris hotel">
    <td>paris hotel</td>
 </tr>
</table>

修改

如果你需要检查更多课程,你可以做什么:
假设您有.agentname li.bedrooms li.saleorrent li,请为每个创建一个数组:

agentname = [], bedrooms = [], saleorrent = [];

.each()功能中,您还需要添加这些选择器:

$('.location li.selected, .propertytype li.selected, .agentname li.selected, .bedrooms li.selected, .saleorrent li.selected').each(function(e){ //...

甚至:

$('.location, .propertytype, .agentname, .bedrooms, .saleorrent').find('.selected').each(function(e){ //...

之后,在function(e){ }内,您需要检查要填充标记信息的数组(可以使用.hasClass()进行验证)。

else if($(this).parent().hasClass('agentname')){ /*fill agentname array*/ }
else if($(this).parent().hasClass('bedrooms')){ /*fill bedrooms array*/ }
//to all the others

最后,检查数组是否为空并使用您的函数,具体取决于if/else语句是否为真:

if(/*array*/.length > 0){ /*do what you need*/ }else{ /*if array is empty*/ }

请记住:如果您需要检查所有类,请记住使用以.(点)开头的名称填充数组,并使用.join(", ")返回所有类名在jQuery选择器中。