【问题标题】:How can I add infinite scrolling to this Angular carousel?如何向这个 Angular 轮播添加无限滚动?
【发布时间】:2019-01-03 15:23:15
【问题描述】:

我关注了this fantastic article,它演示了如何在 Angular 中使用两个指令和一个组件制作一个简单的轮播。

功能集非常有限,不包括我想添加的“无限滚动”模式。

通过'无限滚动' - 我的意思是这样的jQuery等价物:

var carousel = $('#carousel'),
  threshold = 150,
  slideWidth = 500,
  dragStart,
  dragEnd;

$('#next').click(function() {
  shiftSlide(-1)
})
$('#prev').click(function() {
  shiftSlide(1)
})

carousel.on('mousedown', function() {
  if (carousel.hasClass('transition')) return;
  dragStart = event.pageX;
  $(this).on('mousemove', function() {
    dragEnd = event.pageX;
    $(this).css('transform', 'translateX(' + dragPos() + 'px)')
  })
  $(document).on('mouseup', function() {
    if (dragPos() > threshold) {
      return shiftSlide(1)
    }
    if (dragPos() < -threshold) {
      return shiftSlide(-1)
    }
    shiftSlide(0);
  })
});

function dragPos() {
  return dragEnd - dragStart;
}

function shiftSlide(direction) {
  if (carousel.hasClass('transition')) return;
  dragEnd = dragStart;
  $(document).off('mouseup')
  carousel.off('mousemove')
    .addClass('transition')
    .css('transform', 'translateX(' + (direction * slideWidth) + 'px)');
  setTimeout(function() {
    if (direction === 1) {
      $('.slide:first').before($('.slide:last'));
    } else if (direction === -1) {
      $('.slide:last').after($('.slide:first'));
    }
    carousel.removeClass('transition')
    carousel.css('transform', 'translateX(0px)');
  }, 700)
}
$carousel-width: 600px;
$carousel-height: 300px;
body {
  background: #333;
  color: #fff;
  font-size: 22pt;
  text-align: center;
  font-family: 'Teko';
  letter-spacing: 0.15em;
}

body * {
  -webkit-user-select: none
}

.wrap {
  position: relative;
  width: $carousel-width;
  height: 300px;
  margin: 0 auto;
  box-shadow: 7px 7px 5px 0px rgba(0, 0, 0, 0.25);
}

.window {
  overflow: hidden;
  position: relative;
  background: #222;
}

#carousel {
  width: 10000px;
  position: relative;
  top: 0;
  left: -450px;
}

.slide {
  height: 300px;
  width: 500px;
  cursor: pointer;
  float: left;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.slide#b1 {
  background: #556270
}

.slide#b2 {
  background: #4ECDC4
}

.slide#b3 {
  background: #9CE462
}

.slide#b4 {
  background: #FF6B6B
}

.slide#b5 {
  background: #C44D33
}

#prev,
#next {
  cursor: pointer;
  position: absolute;
  bottom: -40px;
  font-size: 14pt;
}

#prev {
  left: 0
}

#next {
  right: 0
}

.transition {
  transition: .7s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>INFINITE CAROUSEL</h1>
<div class="wrap">
  <div class="window">
    <div id="carousel">
      <span class="slide" id="b1">SLIDE-1</span>
      <span class="slide" id="b2">SLIDE-2</span>
      <span class="slide" id="b3">SLIDE-3</span>
      <span class="slide" id="b4">SLIDE-4</span>
      <span class="slide" id="b5">SLIDE-5</span>
    </div>
  </div>
  <span id="prev">PREV</span>
  <span id="next">NEXT</span>
</div>

(轮播可以在每个方向无限滚动,同时保持幻灯片的正确顺序)


我尝试了多种方法来添加此功能,但都没有成功,我尝试过(随后删除):

  • 在当前查看的子集的任一侧动态添加和删除幻灯片块 - 即,如果轮播包含 3 张幻灯片,我将在原始 `1-2-3 1-2-3 的任一侧复制它们,并且然后在用户滚动时添加/删除块。这几乎奏效了,唯一的问题是 Angular 在删除块并疯狂地旋转轮播时感到困惑,因为它仍然引用了一个不再存在的幻灯片编号。

  • 动态添加和删除单个幻灯片,类似于上述方法。同样的问题。

  • 直接复制幻灯片数百次。这行得通,但显然性能极差,而且看起来很愚蠢。

这是stackblitz showing what I've got so far

【问题讨论】:

  • 似乎对我有用...您有什么问题要报告吗?
  • 旋转木马可以工作,这不是我的问题——我想了解如何向它添加无限滚动
  • 但是您确实可以无限滚动!这就是为什么我要问你是否有问题,因为 SOF 是针对问题的。如果您想找到进行无限滚动的最佳代码,我不确定这是问这个的地方。试试Code Review 可能吗?
  • 哦,我明白了。您不希望轮播回到第一张幻灯片,而是希望将其视为第四张幻灯片?
  • 不,我没有无限滚动 - 我有一些东西可以水平向后滚动并在您超过最大幻灯片数或在最小幻灯片数之前重置。这基本上是一个我正在寻求帮助修复的错误。

标签: angular


【解决方案1】:

更新 (当我们在最后一个和第二个滑块中时,我重新排序查询列表之前)

有一个解决方法。关键是在最后一个(在进行下一个之前)或第一个(在进行上一个之前)时重新排序 QueryList 并更改 currentSlide

首先更改函数 transitionCarrousel 以允许在 0 秒内“动画”

  private buildAnimation(offset, time: any) {
    return this.builder.build([
      animate(time == null ? this.timing : 0, 
          style({ transform: `translateX(-${offset}px)` }))
    ]);
  }

函数 next 和 prev 变成了类似

next() {
    //if we are in the last 
    if (this.currentSlide + 1 == this.items.length) {
      //reorder the QueryList, 
      let arr = this.items.toArray();
      let first = arr.shift();  //remove the first element
      arr = arr.concat([first]);  //Concat at last of the array
      this.items.reset(arr);
      this.currentSlide--;  //less currentSlide
      this.transitionCarousel(0); //execute the animation in 0 seconds
    }
    this.currentSlide = (this.currentSlide + 1) % this.items.length;
    this.transitionCarousel(null);
  }

  prev() {
    //If we are in the first one
    if (this.currentSlide  == 0) {
      let arr = this.items.toArray();
      let last = arr.pop();  //remove the last element
      arr = [last].concat(arr); //create an array with the last element+arr
      this.items.reset(arr);
      this.currentSlide++;  //change the currentSlide
      this.transitionCarousel(0);  //execute the animation in 0 seconds
    }
    this.currentSlide =
      (this.currentSlide - 1 + this.items.length) % this.items.length;
    this.transitionCarousel(null);
  }

你可以在stackblitz看到工作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2022-10-17
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 2021-10-06
    相关资源
    最近更新 更多