前端 - 纯JS手撸轮播

327 阅读1分钟

代码没有技术含量,适合新手,老鸟忽略,有什么不足请指出。 前几天在网上看到一遍文章说前端轮播的,刚好没什么事,也好久没有撸代码了,心血来潮就写了一个轮播。

废话不多说,先看看效果

四张图片向前向后都可以无缝连接

第一步,渲染4张图片,处理好最前最后一张即可

思路: 图片位置在第1张,如果向左切换,在你触摸的时候,直接将第4张移到第1张前。 图片位置在第4张,如果向右切换,在你触摸的时候,直接将第1张移到第4张后。 正常切换直接偏移距离即可。 代码很简单,重要的是原理。

第二步,初始化设置

第三步,渲染

第四步,添加事件,并切换

根据触摸调整偏移。 当图片被拖动的距离超过屏幕30%,那么松手会自动切换到下一张或者上一张, 否则回弹。

_bind(){
    this.cont = this.elem.querySelector('.g-swiper__content');
    this.list = this.cont.querySelectorAll('.g-swiper-item');
    this.first = this.cont.querySelector('.g-swiper-item:first-child');
    this.last = this.cont.querySelector('.g-swiper-item:last-child');

    this.cont.addEventListener('touchstart', (e)=>{
        var touchs = e.changedTouches[0];
        this.startpoint = {x: touchs.pageX, y: touchs.pageY};
        this._stop();
    });
    this.cont.addEventListener('touchmove', (e)=>{
        this._touchmove(e);
    });
    this.cont.addEventListener('touchend', (e)=>{
        this._touchend(e);
        this._play();
    });
}
_touchmove(e){
    var touchs = e.changedTouches[0];
    this.movepoint = {x: touchs.pageX, y: touchs.pageY};

    var moveX = this.movepoint.x - this.startpoint.x;

    this._setFirstLast(moveX);
    this._touchDirec(moveX);
}
_touchend(e){
    var touchs = e.changedTouches[0];
    this.endpoint = {x: touchs.pageX, y: touchs.pageY};

    var moveX = this.endpoint.x - this.startpoint.x;
    var ismove = Math.abs(moveX) > this.width * 0.3 ? true : false;

    if (ismove) {
        if (moveX > 0) {
            this.prev();
        } else {
            this.next();
        }
    }
    this._transform();
}
// 跟手移动
_touchDirec(direction){
    if (this.index == 0) {
        this.transformX = 0;
    } else if (this.index == this.list.length - 1) {
        this.transformX = -this.index * this.width;
    }
    this.cont.style.transitionDuration = `0ms`;
    this.cont.style.transform = `translateX(${this.transformX + direction}px)`;
}
// 设置偏移
_transform(){
    this.cont.style.transform = `translateX(${this.transformX}px)`;
    this.cont.style.transitionDuration = `500ms`;
}

到这里基本完成轮播。

最后上全代码

最后有点时间实现了自动轮播。

class swiper{
      constructor(opts = {}){
          this.el = opts.el || null;
          this.urls = opts.urls || [];
          this.index = opts.index || 0;
          this.autoplay = opts.autoplay || false;
          this.autotime = opts.autotime || 3000;
          this.timer = null;
          this.width = document.body.clientWidth;
          this.transformX = -this.index * this.width;
          this.startpoint = this.movepoint = this.endpoint = [];
          if (this.el == '' || this.el == null || this.el == undefined) {
              throw('el is undefined');
          }
          this._init();
      }
      _init(){
          this._render();
          this._bind();
          this._transform();
          this._play();
      }
      _render(){
          var html = `<div class="g-swiper__content" style="width:${this.width}px">`;
          for (var url of this.urls) {
              html += `<div class="g-swiper-item"><img src="${url}" alt="" style="width:${this.width}px"></div>`;
          }
          html += '</div>';
          this.elem = document.querySelector(this.el);
          this.elem.innerHTML = html;
      }
      _bind(){
          this.cont = this.elem.querySelector('.g-swiper__content');
          this.list = this.cont.querySelectorAll('.g-swiper-item');
          this.first = this.cont.querySelector('.g-swiper-item:first-child');
          this.last = this.cont.querySelector('.g-swiper-item:last-child');

          this.cont.addEventListener('touchstart', (e)=>{
              var touchs = e.changedTouches[0];
              this.startpoint = {x: touchs.pageX, y: touchs.pageY};
              this._stop();
          });
          this.cont.addEventListener('touchmove', (e)=>{
              this._touchmove(e);
          });
          this.cont.addEventListener('touchend', (e)=>{
              this._touchend(e);
              this._play();
          });
      }
      _play(){
          if (this.autoplay) {
              this.timer = setInterval(() => {
                  this.next();
              }, this.autotime);
          }
      }
      _stop(){
          if (this.autoplay) {
              this.timer && clearInterval(this.timer);
          }
      }
      _touchmove(e){
          var touchs = e.changedTouches[0];
          this.movepoint = {x: touchs.pageX, y: touchs.pageY};

          var moveX = this.movepoint.x - this.startpoint.x;

          this._setFirstLast(moveX);
          this._touchDirec(moveX);
      }
      _touchend(e){
          var touchs = e.changedTouches[0];
          this.endpoint = {x: touchs.pageX, y: touchs.pageY};

          var moveX = this.endpoint.x - this.startpoint.x;
          var ismove = Math.abs(moveX) > this.width * 0.3 ? true : false;

          if (ismove) {
              if (moveX > 0) {
                  this.prev();
              } else {
                  this.next();
              }
          }
          this._transform();
      }
      go(index){
          if (index < 0 || index >= this.urls.length) {
              return false;
          }
          var direction = this.index > index ? 1 : -1;
          this.index = index;
          this._setFirstLast(direction);
          setTimeout(()=>{
              this._go(index);
          })
      }
      _go(index){
          if (index < 0 || index >= this.urls.length) {
              return false;
          }
          this.index = index;
          this.transformX = -this.index * this.width;
          this._transform();
      }
      _setFirstLast(direction){
          var firstTransformX = '', lastTransformX = '';
          if (this.index == 0 && direction > 0) {
              lastTransformX = `translateX(${-this.list.length * this.width}px)`;
          } else if (this.index == this.list.length - 1 && direction < 0) {
              firstTransformX = `translateX(${this.list.length * this.width}px)`;
          }
          if (this.first) {
              this.first.style.transform = firstTransformX;
          }
          if (this.last) {
              this.last.style.transform = lastTransformX;
          }
      }
      _touchDirec(direction){
          if (this.index == 0) {
              this.transformX = 0;
          } else if (this.index == this.list.length - 1) {
              this.transformX = -this.index * this.width;
          }
          this.cont.style.transitionDuration = `0ms`;
          this.cont.style.transform = `translateX(${this.transformX + direction}px)`;
      }
      next(){
          this._setFirstLast(-1);
          this._touchDirec(-1);
          if (this.index == this.list.length - 1) {
              this.index = 0;
              this.transformX = -this.list.length * this.width;
          } else {
              this.index++;
              this.transformX = -this.index * this.width;
          }
          setTimeout(()=>{
              this._transform();
          })
      }
      prev(){
          this._setFirstLast(1);
          this._touchDirec(1);
          if (this.index == 0) {
              this.index = this.list.length - 1;
              this.transformX = this.width;
          } else {
              this.index--;
              this.transformX = -this.index * this.width;
          }
          setTimeout(()=>{
              this._transform();
          })
      }
      _transform(){
          this.cont.style.transform = `translateX(${this.transformX}px)`;
          this.cont.style.transitionDuration = `500ms`;
      }
  }