【问题标题】:Looking for a first and last class for grouping items with javascript寻找使用 javascript 对项目进行分组的第一类和最后一类
【发布时间】:2014-04-01 04:28:28
【问题描述】:

我的要求与传统的get first and last方法略有不同,所以我请求专家帮助。

我会用代码示例来解释

我的代码结构是

<div class="wrap">
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a"></div>
</div>

当我使用如下的 jquery 方法时

$('div.group-a:first').addClass('first');
$('div.group-a:last').addClass('last');

结果是这样的

<div class="wrap">
<div class="group-a first"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a last"></div>
</div>

但我希望结果应该如下所示,每个组的第一节课和最后一节课。

<div class="wrap">
<div class="group-a first"></div>
<div class="group-a"></div>
<div class="group-a"></div>
<div class="group-a last"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-b"></div>
<div class="group-a first"></div>
<div class="group-a"></div>
<div class="group-a last"></div>

是否可以使用 javascript 或 jquery?

【问题讨论】:

  • 是的,我的代码结构和上面一样,不幸的是我无法对其进行任何更改,因为它来自外部插件
  • 在查看以下答案后,我想再分享一个信息。我的代码结构不是静态的,有机会出现许多具有不同类的 div,例如 group-a、group-b、group-c、group-d 等。所以我正在寻找一个动态的解决方案,比如 BoltClock 的答案。

标签: javascript jquery


【解决方案1】:

既然可以使用 CSS 相邻兄弟选择器和 :not,为什么还要遍历这些类?这是一个更清洁的方法!

// adding first
$(':not(.group-a) + .group-a, .group-a:first').addClass('first');

// adding last
$('.group-a:last').addClass('last');
$('.group-a + :not(.group-a)').prev().addClass('last');

请注意,这适用于任意数量的group-agroup-b,以及其他类,如group-c,根据要求。 prev() 是必需的,因为对于 CSS 邻接选择器,只能选择第二个元素,而不是第一个元素。希望这会有所帮助!

Demo Here

【讨论】:

    【解决方案2】:

    天真的方法是到iterate through each .group-a element 并检查它是第一个孩子还是直接在.group-b 之后,如果它是最后一个孩子还是直接在.group-b 之前:

    $('div.group-a').each(function() {
        var t = $(this);
    
        if (t.is(':first-child, div.group-b + div')) {
            t.addClass('first');
        }
    
        if (t.is(':last-child') || t.next('div.group-b').length > 0) {
            t.addClass('last');
        }
    });
    

    您需要使用.next() 方法来检查其下一个兄弟,因为没有用于匹配另一个之前的元素的选择器。

    (You can use .prev() in lieu of the + selector if you like your if statements to be congruent.)

    只要您只寻找.group-a 元素,就可以轻松地将其应用于任意数量的组,只需将.group-b 替换为:not(.group-a)

        if (t.is(':first-child, div:not(.group-a) + div')) {
            t.addClass('first');
        }
    
        if (t.is(':last-child') || t.next('div:not(.group-a)').length > 0) {
            t.addClass('last');
        }
    

    【讨论】:

    • 谢谢,希望它能解决我的问题,我会在尝试后发布回放。
    【解决方案3】:

    更新

    function colorFirstLast(thisClass){
        $('div').find("."+thisClass).each(function () {
            var node = $(this);
            var prevNode = node.prev();
            var nextNode = node.next();
            if (prevNode == undefined || !prevNode.hasClass(thisClass)) {
                node.addClass('first');
            }
            if (nextNode == undefined || !nextNode.hasClass(thisClass)) {
                node.addClass('last');
            }
        });
    }
    
    colorFirstLast('group-a');
    

    查看工作代码:

    JSFiddle

    【讨论】:

    • 使用正则表达式匹配整个类名并不是一个好主意。请改用.hasClass()
    • @BoltClock 很高兴知道。谢谢!
    【解决方案4】:

    将组包装在一起然后只对每个组使用 first 和 last 有什么问题吗?

    <div class="wrap">
    <div>
        <div class="group-a first"></div>
        <div class="group-a"></div>
        <div class="group-a"></div>
        <div class="group-a last"></div>
    </div>
    <div class="group-b"></div>
    <div class="group-b"></div>
    <div class="group-b"></div>
    <div>
        <div class="group-a first"></div>
        <div class="group-a"></div>
        <div class="group-a last"></div>
    </div>
    

    【讨论】:

    • 不幸的是,我无法对代码结构进行任何更改,因为它来自外部插件
    【解决方案5】:

    一种方法是使用.prev 方法:

    $(".group-a:first").addClass("first");  // the normal one
    $(".group-a:last").addClass("last");    // the normal one
    
    
    $(".group-b:first").prev(".group-a").addClass("last");  // the `.group-a` which is followed by the first `.group-b`
    
    $(".group-b + .group-a").addClass("first"); // the `.group-a` whose previous element is `.group-b`
    

    DEMO

    【讨论】:

      【解决方案6】:

      您可以通过过滤具有类 group-a 的连续元素来获取组

      Live Demo

      arr = [];
      groupDivs = $('.wrap div')
      groupDivs.each(function(index){   
         if(this.className == 'group-a') 
             arr.push($(this));
          if(this.className != 'group-a' || index == groupDivs.length-1)
          {
              if(arr.length > 0)
                  arr[0].addClass('first');
              if(arr.length > 1)
                  arr[arr.length-1].addClass('last');        
              arr.length = 0;
          }    
      });
      

      【讨论】:

        【解决方案7】:
        $(".group-a:eq(0), .group-b + .group-a")
        .addClass("first")
        .addBack()
        .find(".group-a:eq(-1), .group-a:eq(3)")
        .addClass("last")
        

        jsfiddle http://jsfiddle.net/guest271314/jF868/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-04-04
          • 1970-01-01
          • 2016-10-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-14
          相关资源
          最近更新 更多