一段时间后,jQuery切换功能失败了

时间:2015-07-18 02:16:33

标签: javascript jquery

我编写了一个jQuery切换函数,如下所示:

// category filter
$.fn.clickToggle = function(a, b) {
  var ab = [b, a];
  function cb(){ ab[this._tog^=1].call(this); }
  return this.on('click', cb);
};

$.fn.swapClass = function(oldClass, newClass) {
  return $(this).removeClass(oldClass)
                .addClass(newClass)
                .fadeIn('fast');
};

$('.category-filter').clickToggle(function() {
  // clear old
  $('.category-filter').each(function() {
    $(this).fadeTo('fast', 1.0);
    $(this).swapClass('label-success', 'label-default');
  })

  // get new
  var category = $(this).attr('data-category');
  $(this).swapClass('label-default', 'label-success');

  // apply new
  $('.category-filter').each(function() {
    if (!($(this).attr('data-category').indexOf(category) >= 0)) {
      $(this).fadeTo('fast', 0.5);
    }
  })
  $('.article_container').each(function() {
    if ($(this).attr('data-categories').indexOf(category) >= 0) {
      $(this).fadeIn('fast');
    } else {
      $(this).fadeOut('fast');
    }
  })
}, function() {
  $(this).swapClass('label-success', 'label-default');
  $('.article_container').each(function() { $(this).fadeIn('fast') })
  $('.category-filter').each(function() { $(this).fadeTo('fast', 1.0) })
});

它运作正常 - 请参阅JSFiddle here - 但点击一个链接然后"跳过"要点击另一个链接,切换似乎就会中断。

我的功能出了什么问题?如何更改它以便切换用户是否再次单击同一链接或下一个链接?

2 个答案:

答案 0 :(得分:2)

这是因为即使您在点击其他元素时更改了其他元素的样式,也没有更改._tog值。

您正试图以两种不同的方式维持状态。一个通过._tog和另一个通过类label-success / label-default。我建议不要使用._tog并依赖这些类。事实上,我会大大简化你的整个javascript。

更新对不起,这只是一个快速的答案,我必须运行,但在这里你去: https://jsfiddle.net/uh123qwx/3/

$('.category-filter').click(function(){
    $('.category-filter').not(this).removeClass('active');
    $(this).toggleClass('active');
});
.category-filter { background-color: #777; transition: all .5s ease-in-out; }
.category-filter.active { color: green; background-color: #5cb85c; }

.category-filter.active[data-category='custom article'] ~ div > .article_container:not([data-categories*='custom article']),
.category-filter.active[data-category='retirement'] ~ div > .article_container:not([data-categories*='retirement']),
.category-filter.active[data-category='property'] ~ div > .article_container:not([data-categories*='property'])
{
    display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="label category-filter" data-category="custom article">custom article</span>
<span class="label category-filter" data-category="retirement">retirement</span>
<span class="label category-filter" data-category="property">property</span>

<div>
  <div class="article_container" data-categories="custom article">
    <p>Custom</p>
  </div>
  <div class="article_container" data-categories="custom article">
    <p>Another custom</p>
  </div>
  <div class="article_container" data-categories="retirement">
    <p>Retirement</p>
  </div>
  <div class="article_container" data-categories="property">
    <p>Property</p>
  </div>
  <div class="article_container" data-categories="property retirement">
    <p>Property and retirement</p>
  </div>
</div>

答案 1 :(得分:1)

您没有正确创建插件,可以让他们为您完成更多的工作。

首先重要的是要意识到当选择器匹配多个元素时...插件中的this包含整个集合。

因此,插件通常包含this.each()部分以隔离实例。通常它看起来像return this.each(){ //instance code });

不是在插件中迭代通常会完成的集合,而是在其他代码中的相同元素集合上进行一大堆迭代,而不需要在那里