H5 js手写一个联动的轮播图

H5 js手写一个联动的轮播图

在这里插入图片描述

事件名使用到的事件
过渡事件transitionend
触摸事件touchstart
滑动事件touchmove
离开事件touchend

同一时间多次拖拽,滑动页面会导致页面无法滑动,属于正常现象,等定时器自动轮播一张图片就会恢复,(原因:新增了节流阀,防止一次划过多张图片)

// html代码
<template>
  <div class="box">
    <div class="swiper111">
      <div class="container">
        <ul
          ref="imgBox11"
          @transitionend="animateEnd"
          @touchstart="touchstart"
          @touchmove="touchmove"
          @touchend="touchend"
        >
          <li><img :src="imgList[imgList.length - 1].img" alt="" /></li>
          <li v-for="(item, index) in imgList" :key="index">
            <img :src="item.img" alt="" />
          </li>
          <li><img :src="imgList[0].img" alt="" /></li>
        </ul>
      </div>
    </div>
    <div class="swiper222">
      <div class="container">
        <ul
          ref="imgBox22"
          @transitionend="animateEnd"
          @touchstart="touchstart"
          @touchmove="touchmove"
          @touchend="touchend"
        >
          <li><img :src="imgList[imgList.length - 1].img" alt="" /></li>
          <li v-for="(item, index) in imgList" :key="index">
            <img :src="item.img" alt="" />
          </li>
          <li><img :src="imgList[0].img" alt="" /></li>
        </ul>
      </div>
    </div>
  </div>
</template>

js部分

<script>
export default {
  name: "",
  components: {},
  filter: {},
  mixins: {},
  props: {},
  data() {
    return {
      imgArr: [
        {
          img: "http://img.hb.aicdn.com/adbde61e4343dedd21e97ea7f22666825a8db7d077ffe-qn8Pjn_fw658",
        },
        {
          img: "http://img.hb.aicdn.com/adeed7d28df6e776c2fa6032579c697381d1a82b7fe00-fwRqgn_fw658",
        },
        {
          img: "http://img.hb.aicdn.com/ab7f48509b3c0353017d9a85ef1d12400c9b2724540d4-p3zouo_fw658",
        },
        {
          img: "http://img.hb.aicdn.com/60f788fc2a846192f224b9e6d4904b30e54926211d3d67-ACFJ9G_fw658",
        },
      ], // 放图片的数组
      flag: true, // 节流阀 防止快速滑动
      imgIndex: 0, // 当前展示图片
      timer: null, // 圆点定时器
      imgWidth: 0, // 图片宽度
      startX: 0, // 手指开始触摸位置
      moveX: 0, // 手指移动距离
      interval: 2000, // 滚动间隔时间
    };
  },
  watch: {},
  computed: {
    translateX() {
      // 计算图片ul当前距离
      return -(this.imgWidth + this.imgWidth * this.imgIndex);
    },
  },

  created() {},
  mounted() {
    this.imgWidth = window.innerWidth; // 获取图片宽度
    // ul先左移动一个图片距离,显示第一张图片
    this.$refs.imgBox11.style.transform = `translateX(-${this.imgWidth}px)`;
    this.$refs.imgBox22.style.transform = `translateX(-${this.imgWidth}px)`;
    this.timer = setInterval(() => {
      // 自动轮播
      this.imgIndex++;
      this.circleIndex++;
      this.$refs.imgBox11.style.transition = "all .5s"; // 切换下一张图片
      this.$refs.imgBox22.style.transition = "all .5s"; // 切换下一张图片
      this.$refs.imgBox11.style.transform = `translateX(${this.translateX}px)`;
      this.$refs.imgBox22.style.transform = `translateX(${this.translateX}px)`;
    }, this.interval);
  },

  updated() {},
  activated() {},
  destroyed() {},
  methods: {
    // 过渡结束事件
    animateEnd() {
      if (this.imgIndex >= this.imgArr.length) {
        // 判断当前图片索引是否为最后一张图
        this.imgIndex = 0;
        this.$refs.imgBox11.style.transition = "none"; // 迅速跳转至第一张图
        this.$refs.imgBox22.style.transition = "none"; // 迅速跳转至第一张图
        this.$refs.imgBox11.style.transform = `translateX(-${this.imgWidth}px)`;
        this.$refs.imgBox22.style.transform = `translateX(-${this.imgWidth}px)`;
      }
      if (this.imgIndex < 0) {
        // 判断当前图片索引是否为第一张图
        this.imgIndex = this.imgArr.length - 1;
        this.$refs.imgBox11.style.transition = "none"; // 迅速跳转至最后一张图
        this.$refs.imgBox22.style.transition = "none"; // 迅速跳转至最后一张图
        this.$refs.imgBox11.style.transform = `translateX(${this.translateX}px)`;
        this.$refs.imgBox22.style.transform = `translateX(${this.translateX}px)`;
      }
      this.flag = true; // 打开节流阀
    },

    // 手指开始触摸事件
    touchstart(event) {
      clearInterval(this.timer); // 关闭自动轮播
      if (this.flag) {
        this.startX = event.targetTouches[0].clientX; // 获取开始触摸位置
      }
    },
    // 手指开始移动
    touchmove(event) {
      if (this.flag) {
        this.moveX = event.targetTouches[0].clientX - this.startX; // 手指移动位置
        this.$refs.imgBox11.style.transition = "none"; // 图片ul跟随手指移动
        this.$refs.imgBox22.style.transition = "none"; // 图片ul跟随手指移动
        this.$refs.imgBox11.style.transform = `translateX(${
          this.translateX + this.moveX
        }px)`;
        this.$refs.imgBox22.style.transform = `translateX(${
          this.translateX + this.moveX
        }px)`;
      }
    },
    // 结束触摸
    touchend(event) {
      if (this.flag) {
        if (this.moveX > 80) {
          // 移动距离大于80,图片索引--
          this.imgIndex--;
          this.circleIndex--;
        } else if (this.moveX < -80) {
          // 移动距离小于-80,图片索引++
          this.imgIndex++;
          this.circleIndex++;
        }
        this.$refs.imgBox11.style.transition = "all .5s"; // 展示当前索引图片
        this.$refs.imgBox22.style.transition = "all .5s"; // 展示当前索引图片
        this.$refs.imgBox11.style.transform = `translateX(${this.translateX}px)`;
        this.$refs.imgBox22.style.transform = `translateX(${this.translateX}px)`;
      }
      // 触摸事件完成,继续自动轮播
      clearInterval(this.timer); // 防止定时器叠加
      this.timer = setInterval(() => {
        this.imgIndex++;
        this.circleIndex++;
        this.$refs.imgBox11.style.transition = "all .5s";
        this.$refs.imgBox22.style.transition = "all .5s";
        this.$refs.imgBox11.style.transform = `translateX(${this.translateX}px)`;
        this.$refs.imgBox22.style.transform = `translateX(${this.translateX}px)`;
      }, this.interval);
      this.flag = false; // 关闭节流阀,等待动画完成
    },
  },
};
</script>

css样式

<style scoped lang="scss">
.box {
  display: flex;
  .swiper111 {
    width: 100%;
    height: 506px;
    background-color: #39a9ed;
    overflow: hidden;
    position: relative;
    .container {
      width: 375px;
      height: 100%;
      display: flex;
      ul {
        overflow: hidden;
        width: 4500px;
        height: 100%;
        flex-shrink: 0;
        list-style-type: none;
        li {
          float: left;
          width: 750px;
          img {
            width: 100%;
          }
        }
      }
    }
    .circle {
      position: absolute;
      // position: relative;
      justify-content: center;
      ol {
        display: flex;
        bottom: 5px;
        right: 5px;
        margin: 0;
        li {
          display: inline-block;
          width: 20px;
          height: 20px;
          margin-left: 20px;
          background-color: red;
          list-style: none;
          border-radius: 10px;
          transition: all 0.3s;
          .current {
            width: 15px;
          }
        }
      }
    }
  }
  .swiper222 {
    width: 100%;
    height: 600px;
    background-color: #39a9ed;
    overflow: hidden;
    position: relative;
    .container {
      width: 375px;
      height: 100%;
      display: flex;
      ul {
        overflow: hidden;
        width: 4500px;
        height: 100%;
        flex-shrink: 0;
        list-style-type: none;
        li {
          float: left;
          width: 750px;
          img {
            width: 100%;
          }
        }
      }
    }
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值