【问题标题】:How can i not repeat this function我怎么能不重复这个功能
【发布时间】:2026-02-09 21:25:01
【问题描述】:

我的博客上有一个过滤系统,它工作得很好,但我只是想知道我怎么不能一遍又一遍地重复这个功能。

这里是html:

<div class="postFilter">
        <ul>
            <li><a href="#" class="filter filter1 filterActive">all</a></li>
            <li><a href="#" class="filter filter2">another link</a></li>
            <li><a href="#" class="filter filter3">third link</a></li>
            <li><a href="#" class="filter filter4">fourth</a></li>
            <li><a href="#" class="filter filter5">fifth</a></li>
        </ul>
    </div><!-- /.postFilter -->

和我正在使用的 jquery:

$('.filter1').on('click', function(e){
    e.preventDefault();

    // add & Remove filter

    $('.filter').removeClass('filterActive');
    $('.filter1').addClass('filterActive');

    // hide & show categories

    $('.categ').hide();
    $('.categ1').show();
});

$('.filter2').on('click', function(e){
    e.preventDefault();

    // add & Remove filter

    $('.filter').removeClass('filterActive');
    $('.filter2').addClass('filterActive');

    // hide & show categories

    $('.categ').hide();
    $('.categ2').show();
});

我重复了 5 次,我知道我想做什么,我想看看点击的过滤器是否等于 1,2,3,4,5 然后显示响应函数的代码。但我不知道从哪里开始。

忘了说我试过这个:

var filterNum;

$('.filter').on('click', function(e){
    e.preventDefault();

    if($('.filter').hasClass('filter1')){
        filterNum = 1;
    }else if($('.filter').hasClass('filter2')){
        filterNum = 2;
    }else if($('.filter').hasClass('filter3')){
        filterNum = 3;
    }else if($('.filter').hasClass('filter4')){
        filterNum = 4;
    }else if($('.filter').hasClass('filter5')){
        filterNum = 5;
    }

    filterClick(filterNum);
});



function filterClick(number){
    // add & Remove filter

    $('.filter').removeClass('filterActive');
    $('.filter' + number).addClass('filterActive');

    // hide & show categories

    $('.categ').hide();
    $('.categ' + number).show();
}

【问题讨论】:

  • 你的尝试很接近了,但是你可能想要$(this).hasClass()而不是$('.filter').hasClass()
  • 很高兴听到这个消息。虽然您的想法有效,但我个人喜欢下面的经验答案。使用数据属性是避免您的巨大if / else 部分的好方法。你想编写你的代码,这样你就可以拥有 99 个过滤器而不必触摸它,data 方法可以实现这一点,而你的代码需要多 94 行代码:)

标签: jquery html dry


【解决方案1】:

使用this 来指代被点击的元素。除此之外,您还可以使用自定义 data 属性来引用您要显示的类别:

$('.filter').on('click', function(e) {
  e.preventDefault();

  // add & Remove filter
  var $this = $(this);

  $('.filter').removeClass('filterActive');
  $this.addClass('filterActive');

  // hide & show categories
  $('.categ').hide();
  $('.' + $this.data('cat')).show();
});
.filterActive {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="postFilter">
  <ul>
    <li><a href="#" class="filter filterActive" data-cat="categ1">all</a></li>
    <li><a href="#" class="filter" data-cat="categ2">another link</a></li>
    <li><a href="#" class="filter" data-cat="categ3">third link</a></li>
    <li><a href="#" class="filter" data-cat="categ4">fourth</a></li>
    <li><a href="#" class="filter" data-cat="categ5">fifth</a></li>
  </ul>
</div>
<div class="cat">
  <div class="categ categ1">
    Cat1
  </div>
  <div class="categ categ2">
    Cat2
  </div>
  <div class="categ categ3">
    Cat3
  </div>
  <div class="categ categ4">
    Cat4
  </div>
  <div class="categ categ5">
    Cat5
  </div>
</div>

【讨论】:

  • 这可以改进,因为您在单击事件中使用 JQuery 选择器,每次单击时都必须进行选择,这是不必要的,也不是高性能
【解决方案2】:

如果你可以修改 html,我会使用 data-attributes 来简化:

<div class="postFilter">
        <ul>
            <li><a href="#" data-filterid="1" class="filter filterActive">all</a></li>
            <li><a href="#" data-filterid="2" class="filter ">another link</a></li>
            <li><a href="#" data-filterid="3" class="filter ">third link</a></li>
            <li><a href="#" data-filterid="4" class="filter ">fourth</a></li>
            <li><a href="#" data-filterid="5" class="filter ">fifth</a></li>
        </ul>
    </div><!-- /.postFilter -->

$('.filter').on('click', function(e){
    e.preventDefault();

    $('.filter').removeClass('filterActive');
    $(this).addClass('filterActive');

    $('.categ').hide();
    $('.categ' + $(this).data('filterid')).show();
});

【讨论】:

    【解决方案3】:

    这是.categ 在哪里?假设它在&lt;li&gt; 内,这应该可以工作:

    $('.filter').on('click', function(e) {
      e.preventDefault();
      // add & Remove filter
      $('.filter').removeClass('filterActive');
      $(this).addClass('filterActive');
      // hide & show categories
      $('.categ').hide();
      $(this).next('.categ').show();
      /* If .categ is inside the .filter, use this instead:
        $(this).find('.categ').show();
         And if .categ is outside, you'll need to use something like:
        $(this).parents().next('.categ').show();
      */
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <div class="postFilter">
      <ul>
        <li><a href="#" class="filter filter1 filterActive">all</a><span class="categ categ1" style="display: none;">categ</span></li>
        <li><a href="#" class="filter filter2">another link</a><span class="categ categ2" style="display: none;">categ</span></li>
        <li><a href="#" class="filter filter3">third link</a><span class="categ categ3" style="display: none;">categ</span></li>
        <li><a href="#" class="filter filter4">fourth</a><span class="categ categ4" style="display: none;">categ</span></li>
        <li><a href="#" class="filter filter5">fifth</a><span class="categ categ5" style="display: none;">categ</span></li>
      </ul>
    </div>

    【讨论】:

      【解决方案4】:
      var $filters = $('.filter');
      var $filtered = $('.categ');
      
      $filters.on('click', function(){
         $filters.removeClass('filterActive');
         $(this).addClass('filterActive'); 
         $filtered.removeClass('filterActive');
         $filtered.eq(k).addClass('filterActive');  
      });
      

      https://codepen.io/mrbizle/pen/vZKYgq

      这样我们就不必创建大量的 jQuery 对象

      【讨论】: