【问题标题】:Filter through elements with same class but not in the same wrapper过滤具有相同类但不在同一个包装器中的元素
【发布时间】:2015-10-29 05:39:44
【问题描述】:

使用我找到的here 的方法,我正在尝试升级我的previous question 的功能。

基本上,我想使用上一个和下一个按钮循环浏览我的元素。我不能使用 nextAll()prevAll() 函数,因为它们不在同一个包装器中,所以我使用了第一个链接中最受好评的解决方案。下一个循环可以正常工作,而上一个则不行。

var $content = $(".big_container");
var $loaded_content = $(".details");
var $item_selector = $(".item");
var $previous = $('.previous');
var $next = $('.next');

if ($content.length > 0) {
  $item_selector.on('click', function(e) {
    e.preventDefault();
    var $this = $(this);
    load_gallery_container($this);
  });

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

    var $next_item = $content.find('.current').findNext('.item');
    if ($content.find('.item').hasClass('current')) {
      if ($next_item.length) {
        $content.find('.item').removeClass('current');
      }
      load_gallery_container_next_prev($next_item);
    }
  });

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

    var $prev_item = $content.find('.current').findPrev('.item');
    if ($content.find('.item').hasClass('current')) {
      if ($prev_item.length) {
        $content.find('.item').removeClass('current');
      }
      load_gallery_container_next_prev($prev_item);
    }
  });


}

//Next all items

$.fn.findNextAll = function(selector) {
  var that = this[0],
    selection = $(selector).get();
  return this.pushStack(!that && selection || $.grep(selection, function(n) {
    return that.compareDocumentPosition(n) & (1 << 2);
    // if you are looking for previous elements it should be & (1<<1);
  }));
}

$.fn.findNext = function(selector) {
  return this.pushStack(this.findNextAll(selector).first());
}

//Previous all items

$.fn.findPreviousAll = function(selector) {
  var that = this[0],
    selection = $(selector).get();
  return this.pushStack(!that && selection || $.grep(selection, function(n) {
    return that.compareDocumentPosition(n) & (1 << 1);
    // if you are looking for previous elements it should be & (1<<1);
  }).reverse());
}

$.fn.findPrev = function(selector) {
  return this.pushStack(this.findPreviousAll(selector).first());
}

function load_gallery_container_next_prev($container) {
  $loaded_content.find('.div_content').html($container.data('content'));
  $container.addClass('current');
}

function load_gallery_container($container) {
  if ($container.hasClass("current")) {
    $loaded_content.slideUp('slow', function() {
      $(this).removeClass('open');
      $container.removeClass("current");
    });
  } else {

    var $insert_after = $container.parent('.wrappers'),
      $current = $('.current');
    $current.removeClass('current');

    if ($current.parent('.wrappers').is($insert_after)) {
      $loaded_content.find('.div_content').html($container.data('content'));
      $container.addClass("current");
    } else {
      if ($loaded_content.hasClass("open")) {
        $loaded_content.slideUp('slow', function() {
          $(this).removeClass('open');
          $container.removeClass("current");

          $loaded_content.detach().insertAfter($insert_after);
          $loaded_content.find('.div_content').html($container.data('content'));
        });
      } else {
        $loaded_content.detach().insertAfter($insert_after);
        $loaded_content.find('.div_content').html($container.data('content'));
      }

      $loaded_content.slideDown('slow', function() {
        $container.addClass("current");
        $(this).addClass('open');
      });
    }
  }
  setTimeout(function() {
    $('html, body').animate({
      scrollTop: $loaded_content.offset().top - 300
    }, 500);
  }, 600);
}
.big_container {
  background: #141414;
  display: block;
  padding: 30px;
}
.wrappers {
  width: 500px;
  margin: 0 auto;
  display: block;
}
.item {
  width: 31%;
  height: 100px;
  margin-right: 1%;
  margin-bottom: 30px;
  text-align: center;
  background: #ccc;
  color: #fff;
  display: inline-block;
}
.details {
  background: #ddd;
  width: 100%;
  padding: 30px;
  display: none;
}
.navigation {
  display: block;
  text-align: center;
  color: #fff;
}
.previous,
.next {
  font-size: 18px;
  display: inline-block;
  margin: 0 12px 10px;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="big_container">
  <div class="navigation">
    <div class="previous">
      <</div>
        <div class="next">></div>
    </div>
    <div class="wrappers">
      <div class="item" data-content="blabla bla bla blaaaa">Click on meee!</div>
      <div class="item" data-content="blabla BLALALA bla blaaaa">Click on meee!</div>
      <div class="item" data-content="blabla blBLALbla blaaaa">Click on meee!</div>
    </div>
    <div class="wrappers">
      <div class="item" data-content="blabla bla bla randomness">Click on meee!</div>
      <div class="item" data-content="blabla bla bla ">Click on meee!</div>
      <div class="item" data-content="blabla bla bla weeee">Click on meee!</div>
    </div>
    <div class="wrappers">
      <div class="item" data-content="blabla bla bla blaaaa">Click on meee!</div>
      <div class="item" data-content="blabla bla bla???">Click on meee!</div>
      <div class="item" data-content="I am done with blaaaaing">Click on meee!</div>
    </div>
    <div class="details">The content from div goes here:
      <div class="div_content"></div>
    </div>
  </div>

基本上,当我单击上一个时,我会返回到列表中的第一个元素,而不是前一个元素。所以findPrev()函数需要修改,我尝试了很多:将.first()改为.last().prev()甚至.prevAll();尝试更改return that.compareDocumentPosition(n) &amp; (1&lt;&lt;1);

没有任何改变可以使它转到上一个项目。有人知道它有什么问题吗?

回答

好的,所以解决方法是这样的:

$.fn.findPreviousAll = function( selector ){
    var that = this[ 0 ],
    selection = $( selector ).get();
    return this.pushStack(
        !that && selection || $.grep( selection, function(n){
            return that.compareDocumentPosition(n) & (1<<1);
        // if you are looking for previous elements it should be & (1<<1);
        }).reverse()
    );
};

$.fn.findPrev = function( selector ){
    return this.pushStack( this.findPreviousAll( selector ).first() );
};

findPreviousAll 函数所做的是将数组从第一个元素返回到我单击的那个,所以我只需要将它反转!一个简单的.reverse() 做到了:)

我更新了 sn-p,所以它可以工作了! :)

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    改变这个:

    var $prev_item = $content.find('.current').findPrev('.item');
        if ($content.find('.item').hasClass('current')) {
          if ($prev_item.length) {
            $content.find('.item').removeClass('current');
          }
          load_gallery_container_next_prev($prev_item);
        }
    

    到这里:

    var $prev_item = $(".item")[$(".item").index($(".item.current"))-1];
    if($prev_item){
            $(".item.current").removeClass('current');
        }
    $($prev_item).addClass('current');
    load_gallery_container_next_prev($prev_item);
    

    并改变这个:

    function load_gallery_container_next_prev($container) {
      $loaded_content.find('.div_content').html($container.data('content'));
      $container.addClass('current');
    }
    

    到这里:

    function load_gallery_container_next_prev($container) {
        $loaded_content.find('.div_content').html($($container).attr("data-content"));
        $container.addClass('current');
    }
    

    Here is the JSFiddle demo :)

    【讨论】:

    • 工作,有点,但是当您单击上一个中的第一项时,您无法再单击下一个;)我正在尝试查看上一个功能有什么问题,我被困在grep 过滤函数,我知道它返回项目数组,但我只需要设置它返回前一个项目而不是第一个的过滤器。
    • 我没看懂你的意思当你点击前一个项目时,你不能再点击下一步了,你能解释一下吗? :)
    • 我找到了答案,我会更新它。我的意思是,在您的小提琴上,一旦您返回到第一项,当您单击下一步时,什么也没有发生。
    • @dingo_d 我刚刚更新了我的代码,它现在可以工作了,只是缺少一个 if 语句:)
    • @dingo_d 酷,同一个问题的两种解决方案:D
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    相关资源
    最近更新 更多