我有一个用来过滤页面上元素的函数。它将根据过滤对象上的类名称(.filter-boy)检查clicked元素的data属性。

由于功能分为“类别”和“子类别”,因此我想隐藏所有为空的.subcategory父容器。因此,我检查了它们中的每一个,并查看是否所有子chillins被隐藏,如果是,则将一个类.fart-sacks添加到父项。

原谅愚蠢的命名。

$(".feature-dropdown li").click(function() {

  var value = $(this).attr('data-filter');
  if (value === "all") {
    $('.filter-boy').show('1000');
    $('.category_header').show('1000');
    $('header.persona').addClass('hidden');
  } else {
    $('header.persona').not('.' + value).addClass('hidden');
    $('header.persona').filter('.' + value).removeClass('hidden');
    $('.filter-boy').not('.' + value).hide('3000');
    $('.filter-boy').filter('.' + value).show('3000');
    $('.category_header').addClass('hidden');
    $('.feature-filter').addClass('selected');
    $('.feature-filter-small').addClass('selected');
    $('.subcategory').each(function() {
      var chillins = $(this).find('.filter-boy').is(':visible');
      if (!(chillins)) {
        $(this).addClass('fart-sacks');
        console.log(this);
      }
    });
  }
});

标记( slim /中间人)
           .feature-dropdown
              ul
                li.control data-filter="marketing"
                  | Sales & Marketing
                  .unfilter-boy.control title="Clear Filter" data-filter="all"

                li.control data-filter="product_management"
                  | Product Management
                  .unfilter-boy.control title="Clear Filter" data-filter="all"

                li.control data-filter="engineering"
                  | Engineering
                  .unfilter-boy.control title="Clear Filter" data-filter="all"

                li.control data-filter="customer_support"
                  | Customer Support
                  .unfilter-boy.control title="Clear Filter" data-filter="all"

                li.control data-filter="ux_design"
                  | UX Design
                  .unfilter-boy.control title="Clear Filter" data-filter="all"


- data.features_all.features.each do |c|
  section.magellan-container id="#{c.category}"
    .category_header.row.align-center.align-middle.collapse
      .small-12.medium-3.medium-offset-1.small-order-2.medium-order-1.columns
        h2 = c.category
        p = c.category_description
      .small-12.medium-7.medium-offset-1.small-order-1.medium-order-2.columns
        - if c.category_illustration && c.category_video
          video autoplay="autoplay" loop="loop" muted="muted" playsinline="playsinline" height="100%" width="100%"
            source src="/images/features/#{c.category_video}.mp4" type="video/mp4"
            source src="/images/features/#{c.category_video}.webm" type="video/webm"

        - elsif c.category_video
          video autoplay="autoplay" loop="loop" muted="muted" playsinline="playsinline" width="100%"
            source src="/images/features/#{c.category_video}.mp4" type="video/mp4"
            source src="/images/features/#{c.category_video}.webm" type="video/webm"

        - elsif c.category_illustration
          = image_tag "#{c.category_illustration}"
        - else
          | No Asset

    - c.sub_category.each do |sc|
      .subcategory.row.align-center.collapse
        .small-12.medium-4.columns
          .subcat_icon
            = image_tag "features/subcat_icons/#{sc.icon_name}.svg", :alt => "#{sc.sub_category_name}", :class => "subcat_icon svg"
          h3 = sc.sub_category_name
        .small-12.medium-6.columns
          .row.collapse.feature-container
            - sc.feature.each do |feat|
              -if feat.priority == "high"
                div class="#{feat.tags} #{feat.priority} cool-card-wide filter-boy small-11 medium-12 columns"
                  .cool-pic
                    - if feat.screenshot && feat.video
                      video autoplay="autoplay" loop="loop" muted="muted" playsinline="playsinline" height="240" width="320"
                        source src="/video/#{feat.video}.mp4" type="video/mp4"
                        source src="/video/#{feat.video}.webm" type="video/webm"

                    - elsif feat.video
                      video autoplay="autoplay" loop="loop" muted="muted" playsinline="playsinline" height="240" width="320"
                        source src="/video/#{feat.video}.mp4" type="video/mp4"
                        source src="/video/#{feat.video}.webm" type="video/webm"

                    - elsif feat.screenshot
                      = image_tag "/images/features/#{feat.screenshot}"

                    - else
                      | NO ASSETS

                  .cool-wrapper
                    h4 = feat.feature_name
                    p = feat.feature_description
                    - if feat.url
                      a.learnmore href="#{feat.url}" Learn More
              -else
                .small-11.medium-6.columns.filter-boy class="#{feat.tags}"
                  div class="#{feat.priority} cool-card"
                    h4 = feat.feature_name
                    p = feat.feature_description
                    - if feat.url
                      a.learnmore href="#{feat.url}" Learn More

所以发生的事情是发生了过滤器操作,但是subcategory函数没有触发,除非我再次单击.feature-dropdown li

我不是一个聪明的jQuery男孩,所以请耐心等待我。

最佳答案

您在3000ms的跨度内显示/隐藏.filter-boy元素,但是在动画完成之前,您正在.filter-boy回调函数中检查subcategory元素的可见性。 subcategory函数在第二次点击时触发,因为第一次调用的3000ms动画已完成,并且元素.is(':visible') === true结束。

您的第一个选择是等待show()完成,然后再运行subcategory函数。幸运的是,jQuery已经提供了a way to do this

$('.filter-boy').filter('.' + value).show('3000', function(){
  //This fires AFTER the 3000ms transition completes
  $('.subcategory').each(function() {
    var chillins = $(this).find('.filter-boy').is(':visible');
    if (!(chillins)) {
      $(this).addClass('fart-sacks');
      console.log(this);
    }
  });
});

但是,您已经使用.filter-boy标识了希望使其可见的$('.filter-boy').filter('.' + value).show('3000');元素。因此,您可以在subcategory函数中使用类似的方法,该方法不依赖于完整的动画或DOM中可见的元素:
$('.subcategory').each(function() {
  //this is the collection you .show() and is query-able BEFORE the animation completes
  var chillins = $(this).find('.filter-boy.' + value);
  if (!(chillins)) {
    $(this).addClass('fart-sacks');
    console.log(this);
  }
});

10-06 15:05