将上一个下一个控件添加到旋转木马

Add Prev Next Controls to Carousel(将上一个下一个控件添加到旋转木马)
本文介绍了将上一个下一个控件添加到旋转木马的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

摆弄了一下计时器和间隔后,我找到了一个令我满意的解决方案。

参见relevant jsFiddle或以下代码:

HTML:

<div id="foo">irrelevant content</div>

javascript(带jQuery):

var post_array = [ "abc", "123", "xyz" ];
var class_array = [ "red", "blue", "green" ];

var interval = 2000;
var i = 0;
var max = post_array.length;
var id ="#foo";

$(id).html(post_array[0]);
$(id).removeClass().addClass(class_array[0]);

setInterval( function(){
    ++i;
    $(id).fadeOut("slow", function() {
    $(id).html(post_array[i%max]).fadeIn("slow");
    $(id).removeClass().addClass(class_array[i%max]);
  });
}, interval);

现在我在想,添加两个侧箭头使我可以返回到堡垒的最佳方式是什么。

我是否应该在命名函数中编写相关代码,以便在按下按钮时可以调用它并传递索引参数?(在这种情况下,如何作用于相同的索引变量?) 按钮覆盖的最佳实践是什么?

救命! 提前感谢

推荐答案

  • 旋转木马应该是模块化的、可重用的和可扩展的。在需要将另一个Carousel添加到DOM中时,不要复制粘贴JS代码。
  • 为了创建"上一步"/"下一步"按钮,您还需要一个停止间隔的方法:stop
  • 当您将鼠标悬停在旋转木马上时,您需要暂停自动播放以防止出现非常糟糕的用户体验(UX)
  • 不要使用jQuery设置动画。只需将is-active类分配给当前索引幻灯片,然后使用CSS随心所欲地处理该类,即可实现动画效果。
  • 使用变量index(从0开始)跟踪当前幻灯片索引
  • You Might Not Need jQuery

目的是使用简单的class或正确的prototype语法创建一个类实例,使用方式如下:

const myCarousel = new Carousel({
  target: "#carousel-one",
  slides: [
    {
      title: "This is slide one",
      image: "images/one.jpg"
    },
    {
      title: "This is slide two! Yey.",
      image: "images/two.jpg"
    }
  ]
});

所以基本上,您需要一个具有以下方法的构造函数

方法 说明
anim() 如果超过幻灯片或为负数,则修复索引并将动画设置为新索引
prev() 递减指数和触发器anim()
next() 增量索引和触发器anim()
stop() 清除循环间隔(按鼠标键)
play() 开始循环(每pause毫秒触发一次next())
class Carousel {
  constructor(options) {

    Object.assign(this, {
      slides: [],
      index: 0,
      pause: 4000, // Pause between slides
      EL: document.querySelector(options.target || "#Carousel"),
      autoplay: true,
    }, options);

    this.total = this.slides.length;
    this.EL_area = this.EL.querySelector(".Carousel-area");
    this.EL_prev = this.EL.querySelector(".Carousel-prev");
    this.EL_next = this.EL.querySelector(".Carousel-next");

    const NewEL = (tag, prop) => Object.assign(document.createElement(tag), prop);

    // Preload images
    this.ELs_items = this.slides.reduce((DF, item) => {
      const EL_slide = NewEL("div", {
        className: "Carousel-slide"
      });
      const EL_image = NewEL("img", {
        className: "Carousel-image",
        src: item.image,
        alt: item.title
      });
      const EL_content = NewEL("div", {
        className: "Carousel-title",
        textContent: item.title
      });
      EL_slide.append(EL_image, EL_content);
      DF.push(EL_slide);
      return DF;
    }, []);
    this.EL_area.append(...this.ELs_items);

    // Events
    this.EL_prev.addEventListener("click", () => this.prev());
    this.EL_next.addEventListener("click", () => this.next());
    this.EL.addEventListener("mouseenter", () => this.stop());
    this.EL.addEventListener("mouseleave", () => this.play());

    // Init
    this.anim();
    this.play();
  }

  // Methods:

  anim() {
    this.index = this.index < 0 ? this.total - 1 : this.index >= this.total ? 0 : this.index;
    this.ELs_items.forEach((EL, i) => EL.classList.toggle("is-active", i === this.index));
  }

  prev() {
    this.index -= 1;
    this.anim();
  }

  next() {
    this.index += 1;
    this.anim();
  }

  stop() {
    clearInterval(this.itv);
  }

  play() {
    if (this.autoplay) this.itv = setInterval(() => this.next(), this.pause);
  }
}


// Use like:
new Carousel({
  target: "#carousel-one",
  slides: [{
      title: "We're part of nature",
      image: "https://picsum.photos/id/10/400/300"
    },
    {
      title: "Remember to read and learn",
      image: "https://picsum.photos/id/24/400/300"
    },
    {
      title: "Up for a coffee?",
      image: "https://picsum.photos/id/30/400/300"
    },
  ]
});
/* CAROUSEL */

.Carousel {
  position: relative;
  height: 300px;
  max-height: 100vh;
}

.Carousel-slide {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  transition: opacity 0.5s; /* DESIRED SLIDE TRANSITIONS */
  opacity: 0;               /* INACTIVE SLIDE*/
}

.Carousel-slide.is-active { /* ACTIVE SLIDE! */
  opacity: 1;
  z-index: 1;
}

.Carousel-prev,
.Carousel-next {
  position: absolute;
  z-index: 2;
  top: 50%;
  transform: translateY(-50%);
  user-select: none; /* Prevent highlight */
}

.Carousel-prev {
  left: 1em;
}
.Carousel-next{
  right: 1em;
}

.Carousel-image {
  position: absolute;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.Carousel-title {
  position: absolute;
  width: 100%;
  height: 100%;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 3em;
}
<div class="Carousel" id="carousel-one">
  <div class="Carousel-area"></div>
  <button class="Carousel-prev" type="button" aria-label="Previous slide">&larr;</button>
  <button class="Carousel-next" type="button" aria-label="Next slide">&rarr;</button>
  <div class="Carousel-desc"></div>
</div>

使用上面的代码,您可以在单个页面上拥有无限数量的旋转木马,因为每个旋转木马都具有不同的targetID。


ps:或者,如果您的代码跟踪上一个/下一个的方向,则用于递增/递减/环回当前索引的逻辑也可以编写为(前面的伪代码!):

C = (is_next ? ++C : --C) < 0 ? T-1 : C%T;

其中C是当前索引,T幻灯片总数,is_next是一个布尔值,当方向为下一个时为true

这篇关于将上一个下一个控件添加到旋转木马的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)