jQuery: use filter(), but work with both results

后端 未结 6 1724
孤城傲影
孤城傲影 2021-01-01 23:16

In jQuery, filter() reduces your result to those elements that fulfill a certain condition.

This splits the list in two parts. Working with the \"good

相关标签:
6条回答
  • 2021-01-01 23:32
    $.fn.if = function(cond, ontrue, onfalse) {
      this.each(function() {
        if (cond.apply(this)) ontrue.apply(this);
        else onfalse.apply(this);
      });
    };
    
    $('some selector').if(function() {
      // determine result
    }, function() {
      // do something
    }, function() {
      // do something else
    });
    

    I'm not sure it is much more readable than putting an if inside an each manually, though.

    0 讨论(0)
  • 2021-01-01 23:36

    The method recommended by Kobi in plugin form:

    $.fn.invert = function() {
      return this.end().not(this);
    };
    
    $('.foo').filter(':visible').hide().invert().show();
    

    Note that invert() will not add a new element to the jQuery stack but replace the last one:

    $('.foo').filter(':visible').invert().end(); // this will yield $('.foo'), not $('.foo:visible')
    

    Edit: changed prevObject to end() at Tomalak's suggestion.

    0 讨论(0)
  • 2021-01-01 23:40

    I don't know if this is any nicer, but using filter() you could do something like:

    var $others = $();
    
    var $filtered = $('div').filter(function() {
        if(! your filter test) {
            $others.push(this);
        } else {
            return true; 
        }
    });
    
    alert($others.length);
    alert($filtered.length);
    

    EDIT:

    At first I tried it starting with an empty jQuery set $(), and then using add() to populate it with the non-filter results, but couldn't make it work.

    EDIT:

    Updated to use push directly on an empty jQuery object as suggested by Tomalak.

    0 讨论(0)
  • 2021-01-01 23:49

    You might try your hand at writing a jQuery plugin to do this. Check out the code of the filter function, and come up with something that does more precisely what you want. It could be something like:

    $("some selector").processList(predicate, successCallback, failureCallback);
    

    Then you would pass in three callbacks: one that evaluates an object to see if it matches the filter selection (you could also accept a selector string, or the like); one that handles objects that match the selection, and another that handles objects which don't match.

    0 讨论(0)
  • 2021-01-01 23:51

    Interesting question. I see you are leaning toward what I was going to suggest:

    $("some selector").each(function() { 
      if ($(this).is(SOMEFILTER)) { 
        // do something
      } else {
        // do something  
      }
      // continue with things that apply to everything
    }); 
    
    0 讨论(0)
  • 2021-01-01 23:52

    I usually use not for this - it can take an array of elements and remove them from your selection, leaving you with the complement:

    var all = $("some selector");
    var filtered = all.filter(function() {
      // determine result...
      return result;
    });
    var others = all.not(filtered);
    
    0 讨论(0)
提交回复
热议问题