【问题标题】:jQuery filter items with both a checkbox and click带有复选框并单击的jQuery过滤项目
【发布时间】:2013-09-13 01:30:15
【问题描述】:

我有一个列表,我想要一个过滤器,我的复选框工作如this question 所示。

在我的页面上,页面顶部的选项卡已经在工作,如以下代码和this fiddle 所示。

但是它们彼此冲突,因此当前如果您在单击 col 1 的复选框时单击 xtr1,则会删除所有 col 1 并显示所有 xtr1。 例如,我希望它显示所有勾选了 col 1 的 xtra1。我尝试通过添加变量 addchosen 来解决这个问题,如下所示,但无法使其正常工作,如何才能最好地实现这一点?

<div id="nav">
    <a rel="all"  id="all">All</a>
    <a rel="xtr1" id="xtr1">xtr1</a>
    <a rel="xtr2" id="xtr2">xtr2</a>
    <a rel="xtr3" id="xtr3">xtr3</a>
</div>

<form id="refine-cat">
    <span><input type="checkbox" value="1" name="filtercol">cat 1</span>
    <span><input type="checkbox" value="2" name="filtercol">cat 2</span>
    <span><input type="checkbox" value="3" name="filtercol">cat 3</span>
</form>
<form id="refine-col">
    <span><input type="checkbox" value="1" name="filtercat">col 1</span>
    <span><input type="checkbox" value="2" name="filtercat">col 2</span>
    <span><input type="checkbox" value="3" name="filtercat">col 3</span>
    <span><input type="checkbox" value="4" name="filtercat">col 4</span>
</form>
<ul>
    <li class="xtr3 all item cat-3 col-1">col 1 - cat 3 - xtra 3</li>
    <li class="xtr1 all item cat-3 col-1">col 1 - cat 3 - xtra 1</li>
    <li class="xtr1 all item cat-3 col-1">col 1 - cat 3 - xtra 1</li>
</ul>

(列表中有更多项目)

JS

var chosen = "";

jQuery("#nav a").on("click", function (event) {

    jQuery("#nav a").removeClass("current");
    jQuery(this).addClass("current");

    chosen = jQuery(this).attr("rel");

    jQuery(".item").not("." + chosen).hide();
    jQuery("." + chosen).show();

});


var $items = jQuery('.item');
var $cats = jQuery('#refine-cat input[type=checkbox]');
var $cols = jQuery('#refine-col input[type=checkbox]');

$cols.add($cats).on('change', function (e) {
    var cats = $cats.filter(':checked').map(function(){
        return 'cat-' + (this.value || '')
    }).get();
    var cols = $cols.filter(':checked').map(function(){
        return 'col-' + (this.value || '')
    }).get();

    if(cats.length || cols.length){
        var $fitems = $items;
        var addchosen = "";
        if (chosen) {
            addchosen =', .' + chosen;
        }        
        if(cats.length){
            $fitems = $fitems.filter('.' + cats.join(', .') + addchosen );
        }
        if(cols.length){
            $fitems = $fitems.filter('.' + cols.join(', .'));
        }

        $fitems.show();
        $items.not($fitems).hide();
    } else {
        $items.show();
    }
});

【问题讨论】:

    标签: javascript jquery html onclick onchange


    【解决方案1】:

    我稍微修改了您的代码。有一种更简洁的方法可以做到这一点,但我不想改变你的思路。

    所以,我创建了一个名为 refine() 的函数,并且基本上隔离了您的这部分代码并添加了一个过滤器来选择也:

    if(cats.length){
        $fitems = $fitems.filter('.' + cats.join(', .') + addchosen );
    }
    if(cols.length){
        $fitems = $fitems.filter('.' + cols.join(', .'));
    }
    

    所以这个函数会在nav点击和cols/cats变化时被调用,像这样:

    var cats=[], cols=[], $fitems;
    var $items = jQuery('.item');
    var chosen = "";
    
    function refine() {
        $items.show();
        $fitems = $items;
    
        if(chosen.length && chosen != 'all') {
            $fitems = $items.filter('.' + chosen);
        }
        if(cats.length){
            $fitems = $fitems.filter('.' + cats.join(', .'));
        }
        if(cols.length){
            $fitems = $fitems.filter('.' + cols.join(', .'));
        }
    
        $fitems.show();
        $items.not($fitems).hide();
    }
    
    jQuery("#nav a").on("click", function (event) {
    
        jQuery("#nav a").removeClass("current");
        jQuery(this).addClass("current");
    
        chosen = jQuery(this).attr("rel");
    
        refine();
    });
    
    var $cats = jQuery('#refine-cat input[type=checkbox]');
    var $cols = jQuery('#refine-col input[type=checkbox]');
    
    $cols.add($cats).on('change', function (e) {
        cats = $cats.filter(':checked').map(function(){
            return 'cat-' + (this.value || '')
        }).get();
        cols = $cols.filter(':checked').map(function(){
            return 'col-' + (this.value || '')
        }).get();
    
        refine();
    });
    

    这是你的fiddle

    【讨论】:

    • 您知道如果从 json 文件而不是纯 html 加载 html 的语法(使用委托)会是什么吗?我试图将这个问题stackoverflow.com/questions/18839225/… 中的答案应用到您答案的更改部分,但我遇到了语法错误?我试图用 jQuery(document).on("change", "$cols.add($cats)", function ( event) { 但我收到语法错误,无法识别的表达式:$cols.add($cats)
    • 你可以试试这样的:jQuery('#refine-cat input[type=checkbox], #refine-col input[type=checkbox]') 我想你会得到同样的结果结果使用 .add
    • 为了让它在加载数据时工作,你需要将.on应用到一个永远存在的元素中,然后作为second argument传递你想要的元素在change 事件中触发。请提供一个带有 json 的虚拟小提琴,我很乐意为您纠正。真的不需要加载数据,我很容易有我可以看的东西。
    • 感谢您的帮助,我想我实际上也尝试了其中的选择器,但无法获得第二个参数,我已经完成了这个小提琴jsfiddle.net/aaronk85/5SUNS/3,它显示了过滤器工作有静态内容,但在加载 json 时没有,你能在有机会时提供建议吗?
    【解决方案2】:

    我可能不会把它弄得这么复杂。这是一种方法。

    jQuery("#nav a").on("click", function (event) {
        jQuery("#nav a").removeClass("current");
        jQuery(this).addClass("current").attr("rel");
        if(this.id == 'all') $cats.add($cols).prop('checked', false);
        updateResult();
    });
    
    
    var $items = jQuery('.item');
    var $cats = jQuery('#refine-cat input[type=checkbox]');
    var $cols = jQuery('#refine-col input[type=checkbox]');
    
    $cols.add($cats).on('change', function () {
       //Do something....
        updateResult();
    
    });
    
    function updateResult() {
    
        $('ul > li').hide();
    
        var consArray = [];
        consArray = consArray.concat($('#nav > a.current').map(function () {
            return this.rel;
        }).get());
    
        consArray = consArray.concat($cats.filter(':checked').map(function () {
            return 'cat-' + this.value;
        }).get());
    
        consArray = consArray.concat($cols.filter(':checked').map(function () {
            return 'col-' + this.value;
        }).get());
    
        if(consArray.length)
            $('.' + consArray.join('.')).show();
     }
    

    Fiddle

    还有一个更简单的版本:

    function updateResult() {
        $('ul > li').hide();
        var consArray =  $('#nav > a.current').add(
                                  $cats.filter(':checked')).add(
                                  $cols.filter(':checked'))
            .map(function(){
                  if(this.nodeName === 'A') return this.rel;
                  return this.name.replace(/filter/,'') + '-' + this.value;
    
               }).get();
    
        if(consArray.length)
            $('.' + consArray.join('.')).show();
    }
    

    Fiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-07
      • 2016-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      相关资源
      最近更新 更多