按顺序添加一个类,具体取决于数据属性

时间:2017-07-10 18:06:03

标签: javascript jquery css

我有几个显示多个div的链接,具体取决于data-attribute。当我单击其中一个链接,并且有多个具有相应属性的div时,我希望将该类顺序添加到div中,使它们一次加载一个。就像它在准备好的功能中一样,但我已经以某种方式搞砸了它并且无法解决它。

$('.filter_link').on('click', function(e) {
    e.preventDefault();
    var linkAttr = $(this).attr('data-related'); 
    $('.blurb-content').each(function() {
        $(this).removeClass('flip');
        if($(this).attr('data-dest') == linkAttr) {
            // this does not work
            setTimeout(function() {
                $(this).addClass('flip'); //add class with delay
            }, 500);
        }
    });
});

fiddle

2 个答案:

答案 0 :(得分:1)

两个问题:

  1. this内,setTimeout()将不再引用您的元素。因此,您需要将{em>在外部声明为setTimeout()作为变量,并在$(this)内使用该变量而不是.each()。有关此can be found here的更多信息。

  2. 使用setTimeout()迭代项目时,它们基本上同时发生。您的500没有“按顺序”附加,因此它们将同时延迟500和然后。通过为.each()函数提供参数each,并像在您的i中一样,将500 * i更改为与each的迭代相乘第一个showBlurbs()

  3. 编辑:正如您所看到的,我已经重新考虑了您的代码。它现在使用函数.each()简单地淡化每个函数(将参数作为jQuery对象列表)。它解决了对如此多data个循环的需求,并且代码相当简洁。

    其他几点说明:

    • 您可以使用.data("xxx")代替.attr("data-xxx")

    • 获取var linkAttr = $(this).data('related'); $blurbsToShow = $('.blurb-content[data-dest=' + linkAttr + ']'); 属性
    • 不是循环遍历所有项目并检查其数据属性,您只需选择匹配的项目即可:

      $(document).ready(function() {
        
        //Show ALL blurbs at the beginning
        var timeouts = [];
        var $allBlurbs= $(".blurb-content");
        showBlurbs($allBlurbs);
      
      
        //On click, show related blurbs
        $('.filter_link').on('click', function(e) {
          e.preventDefault();
          var linkAttr = $(this).data('related');
          var $relatedBlurbs = $('.blurb-content[data-dest=' + linkAttr + ']');
          showBlurbs($relatedBlurbs);
        });
      
      
        function showBlurbs(blurbs) {
      
          //Clear all pending animations
          for (var i = 0; i < timeouts.length; i++) {
              clearTimeout(timeouts[i]);
          }
      
          //Reset everything to hidden
          timeouts = [];
          $(".blurb-content").removeClass("flip");
      
          //Sequentially trigger the "fade-in" for each blurb
          blurbs.each(function(i) {
            var $self = $(this);
            timeouts.push(setTimeout(function() {
              $self.addClass("flip");
            }, 500 * i));
          });
      
        }
      
      
      });

    .blurb-content {
      opacity: 0;
      display: none;
    }
    
    .flip {
      display: block;
      -webkit-animation: fade-in-bottom 0.6s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
      animation: fade-in-bottom 0.6s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
    }
    
    @-webkit-keyframes fade-in-bottom {
      0% {
        -webkit-transform: translateY(50px);
        transform: translateY(50px);
        op.blurb-content {
          opacity: 0;
          display: none;
        }
        .flip {
          display: block;
          -webkit-animation: fade-in-bottom 0.6s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
          animation: fade-in-bottom 0.6s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
        }
        @-webkit-keyframes fade-in-bottom {
          0% {
            -webkit-transform: translateY(50px);
            transform: translateY(50px);
            opacity: 0;
          }
          100% {
            -webkit-transform: translateY(0);
            transform: translateY(0);
            opacity: 1;
          }
        }
        @keyframes fade-in-bottom {
          0% {
            -webkit-transform: translateY(50px);
            transform: translateY(50px);
            opacity: 0;
          }
          100% {
            -webkit-transform: translateY(0);
            transform: translateY(0);
            opacity: 1;
          }
        }
        acity: 0;
      }
      100% {
        -webkit-transform: translateY(0);
        transform: translateY(0);
        opacity: 1;
      }
    }
    
    @keyframes fade-in-bottom {
      0% {
        -webkit-transform: translateY(50px);
        transform: translateY(50px);
        opacity: 0;
      }
      100% {
        -webkit-transform: translateY(0);
        transform: translateY(0);
        opacity: 1;
      }
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <a href="#" class="filter_link" data-related="1">link1</a>
    <a href="#" class="filter_link" data-related="3">link2</a>
    <a href="#" class="filter_link" data-related="3">link3</a>
    <a href="#" class="filter_link" data-related="2">link4</a>
    
    <div class="blurb-content" data-dest="1">content 1</div>
    <div class="blurb-content" data-dest="1">content 1</div>
    <div class="blurb-content" data-dest="2">content 2</div>
    <div class="blurb-content" data-dest="3">content 3</div>
    {{1}}

答案 1 :(得分:0)

$('.filter_link').on('click', function(e) {
e.preventDefault();
var linkAttr = $(this).attr('data-related'); 
$('.blurb-content').each(function(i) {

    var thisBlurb = $(this);

    thisBlurb.removeClass('flip');
    if(thisBlurb.attr('data-dest') == linkAttr) {
        // this work
        setTimeout(function() {
            thisBlurb.addClass('flip'); //add class with delay
        }, 500 * i );
    }
});});

复制粘贴代码并将.blurb的$(this)更改为在每个循环开始时分配的var thisBlurb。

JavaScript关键字“this”的作用域是它所在的函数.setTimeout使用一个函数,因此setTimeout中的任何“this”不再是元素.blurb。 “this”现在是setTimeout使用的函数:)

我还在“each”循环使用的函数中添加了参数“i”。 “i”是每个循环的索引,并且每循环迭代将增加1。将此索引乘以setTimeout毫秒参数将使您获得所需的效果。