【问题标题】:How to simplify repetitive jQuery code with different selectors如何使用不同的选择器简化重复的 jQuery 代码
【发布时间】:2014-11-17 03:57:49
【问题描述】:

所以我有数百个列表,它们被分为 30 多个类别。

我所做的是让列表显示:无,对于每个类别都有一个 click.slideToggle() 函数,并且除了单击的列表之外,还有 slideUp 其他列表,问题是我必须为每个类别编写重复性很长的代码列表。

我需要有人建议我编写这些 javascript 行的更好方法,所以这里是更清晰图片的代码。

<span id='categoryA'>
<div id='listA' class='list'>

<span id='categoryB'>
<div id='listB' class='list'>

<span id='categoryC'>
<div id='listC' class='list'>

<span id='categoryD'>
<div id='listD' class='list'>

<!-- there are around 25 more of similar lists -->

CSS:

.list {
    display: none;
}

JavaScript:

$(document).ready(function() {
  $("#categoryA").click(function() {
    $("#listA").slideToggle(function() {
      $("#listB,#listC,#listD").slideUp();
    });
  });

   $("#categoryB").click(function() {
    $("#listB").slideToggle(function() {
      $("#listA,#listC,#listD").slideUp();
    });
  });

   $("#categoryC").click(function() {
    $("#listC").slideToggle(function() {
      $("#listA,#listB,#listD").slideUp();
    });
  }); 

   $("#categoryD").click(function() {
    $("#listD").slideToggle(function() {
      $("#listA,#listB,#listC").slideUp();
    });
  });
});

重点是我希望每次点击#categoryA 时,它会滑动切换#listA,如果我点击#categoryB,它会滑动切换#listB 和滑动当前滑动的任何其他列表。

我有 30 多个类别。如何使代码更简单、更高效?有没有人有更聪明的方法来做到这一点?

【问题讨论】:

  • 使用类和单个事件处理程序,然后按 DOM 中的位置定位元素。
  • 顺便说一句,已经有 jQuery 的 accordion 插件,甚至是来自他们的 jQueryUI 小部件集合的 official one 和大量的第三方插件。在推出自己的代码之前,您可能需要检查现有代码。

标签: javascript jquery


【解决方案1】:
<span class='category' id='categoryA'>Title A</span>
<div id='listA' class='list'>...</div>

<span class='category' id='categoryB'>Title B</span>
<div id='listB' class='list'>...</div>

<span class='category' id='categoryC'>Title C</span>
<div id='listC' class='list'>...</div>

<span class='category' id='categoryD'>Title D</span>
<div id='listD' class='list'>...</div>

$(function() {
    $(document).on("click", ".category", function () {
        $(this).next(".list").slideToggle(function () {
            $(".list").not(this).slideUp();
        };
    });
});

备注:

  • 使用 CSS 类(而不是 HTML ID)对相似的元素进行分组。注意我的代码根本不需要 ID,除非你真的需要它们来做其他事情,否则你可以放弃它们。
  • 这使用event delegation
  • .not() 从 jQuery 列表中排除一个元素。
  • .slideToggle() 的“完成”回调中的 this 指的是动画元素(因此,每个动画元素都会调用一次“完成”回调,而不是在所有选定元素都完成滑动之后 - 需要保留的内容请注意,当您在某个时间点为多个元素设置动画时)

【讨论】:

  • 不错!这让我的生活变得轻松多了,非常感谢你的帮助。不过还有一个小问题,我使用 php 多维数组并回显所有元素,并且在每个 ,有没有跳过或忽略
    的命令?如果没有,我会重新安排我的php代码..提前谢谢
  • 首先不要包含&lt;br&gt;&lt;div&gt; 是一个块元素,这意味着它会自行断行(根据需要使用 CSS 创建边距)。虽然您可以修改 jQuery 代码以处理几乎任何类型的 HTML 结构,但将您的 HTML 重新构建为不同的(并且大多数情况下更明智的)形式将导致 HTML 更干净的jQuery代码。因此,虽然您可以使用 $(this).nextAll(".list").first() 之类的东西,但只需清理您的 HTML。 (提示:使用&lt;span&gt; 作为标题类型的项目也不是正确的选择)
  • 是的,非常感谢你的知识,我已经将我的 更改为
    ,只是好奇是否有办法跳过一个元素或其他东西,我还有很多用jquery学习。谢谢
  • 感谢链接!会通读的,我通常从 w3schools.com 阅读我的参考资料,更容易理解,但我想它并不完整。
【解决方案2】:

这是一个非常简单的函数,它使用jQuery.on 来委派事件,并使用.next.not 函数在用户单击触发器时过滤选择。

/**
* @param [jQuery] $obj - the jQuery selection we want to accordionize
* @param [Object] opt  - optional settings
* @return [jQuery] $obj
*/
function accordionize($obj, opt){
    opt = $.extend({
        triggers: 'dt',
        content: 'dd'
    }, opt || {});

    // bind the click events to all elements that match our trigger selection
    $obj.on('click', opt.triggers, function(e){
        // Get the associated content element
        var $target = $(this).next(opt.content);
        $target.slideDown(function(){
            $obj.find(opt.content).not($target).slideUp();
        });    
    });
    // Create a custom event to setup accordion.
    // hides all content elements except the first.
    $obj.on('accordionize.reset', function(){
        $obj.find(opt.content).hide().first().show();
    });

    return $obj.trigger('accordionize.reset');
}

它要求您将内容包装在一个元素中:

<dl class="accordion">
    <dt>Topic One</dt>
    <dd>Ipsum loren</dd>
    <dt>Topic two</dt>
    <dd>Some fun facts about topic two</dd>
    <dt>Topic three</dt>
    <dd>Some fun facts about topic three</dd>
</dl>

<div class="accordion">
    <h3 class="trigger">Topic One</h3>
    <div class="content">Ipsum loren</div>
    <h3 class="trigger">Topic two</h3>
    <div class="content">Some fun facts about topic two</div>
    <h3 class="trigger">Topic three</h3>
    <div class="content">Some fun facts about topic three</div>
</div>

第一个示例使用description list,它非常适合类别列表。

然后像这样调用函数:

accordionize($('dl.accordion'));
accordionize($('div.accordion'), {
  triggers: '.trigger',
  content: '.content'
});

【讨论】:

  • 您可以在jsfiddle.net/maxcal/fqgcwoja/6 试用并查看规格。 (我写这个是为了回答这个问题,我不是在推动一个私人项目)
  • +1 用于展示如何扩展基本功能(尽管我认为编写一个完整的 jQuery 插件稍微超出了此类问题的范围)。不确定您的“不推动私人项目”免责声明是什么意思,但是......
  • 我同意这有点矫枉过正,但我​​想表明分离功能和 DOM 结构可能是一件非常好的事情。 “不推动私人项目” - 我只是不想给人这样的印象,即这是另一个 jQuery 手风琴插件的插件。
  • 哦,好吧。我想提到已经有精心制作的插件可以解决 OP 的问题将是一件好事。
  • 我会 - 如果我知道一个 jQuery 手风琴插件,我会推荐给除了我最大的敌人以外的任何人:)
【解决方案3】:

我的理解是,每当单击类别时,相应的列表都会向下滑动,而类别中的其他列表会向上滑动。如果是这种情况,那么无论何时单击任何类别,然后向上滑动所有列表并仅向下滑动属于该类别的列表。

$(".category").click(function(){
      $(".list).slideUp();
      $(this).find('.list').slideDown();    
});

【讨论】:

    【解决方案4】:

    让我们使用这个。

    html :
    
    <span id='A' class="category">
    <div id='listA' class='list'>
    
    <span id='B'class="category">
    <div id='listB' class='list'>
    
    <span id='C'class="category">
    <div id='listC' class='list'>
    
    <span id='D' class="category">
    <div id='listD' class='list'>
    
    //there are around 25 more of similar lists//
    
    css :
    
    .list {
        display: none;
    }
    
    javascript :
    
    $(document).ready(function() {
      $(".category").click(function(){
          id = jQuery(this).attr("id");
          $(".list").slideUp();
          $("#list"+id).slideToggle();
      });
    });
    

    希望这能如你所愿..

    【讨论】:

      【解决方案5】:

      你可以试试这样的

       $("span").on("click", function(){
        var that = $(this)
        that.slidToggle(function(){
        $("#listA,#listC,#listD").slideUp();});
      

      });

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签