微信小程序自定义轮播图

实现效果



wxml:

<view class='yxxrui-slider'>

  <view style='overflow:hidden;'>

    <view bindtouchcancel="sliderTouchCancel" bindtouchstart='sliderTouchStart' bindtouchend='sliderTouchEnd' bindtouchmove='sliderTouchMove' style='width:{{yxxruiSliderData.totalWidth}}px;display:flex;transform:translate({{yxxruiSliderX}}px,0)'>

        <block wx:for="{{yxxruiSliderData.datas}}" wx:for-index="i" wx:key="i">

          <view class="slider-item" style="padding-left:{{yxxruiSliderData.blankWidth}}px;">

            <form class="slider-form" bindsubmit="" report-submit="true" data-posttype="" data-posturl="" data-appId="">

              <button>

                <image class="slider-img" src="{{item}}"/>

              </button>

            </form>

          </view>

        </block>

      </view>

    </view>

    <view class="slider-indicate-dots">

      <block wx:for="{{yxxruiSliderData.indicateDots}}" wx:for-index="i"  wx:key="i">

        <view class="slider-indicate-dot {{i==yxxruiSliderCurPage-1?'active':''}}">

        </view>

      </block>

    </view>

  </view>

wxss:

/*自定义轮播图样式 */

.yxxrui-slider{

  display: block;

}

.yxxrui-slider .slider-item{

  position:relative;

  display:inline-block;

  width:100%;

  box-sizing:border-box;

  overflow: hidden;

  line-height: 0;

}

.yxxrui-slider .slider-form{

  position:relative;

  display:inline-block;

  width:100%;

}

.yxxrui-slider .slider-img{

  border-radius: 14px;

  width:100%;

  height: 180px;

}

.yxxrui-slider .slider-item button{

  line-height: 0;

  box-sizing: border-box;

  -moz-box-sizing:border-box; /* Firefox */

  -webkit-box-sizing:border-box; /* Safari */

  padding-left: 0;

  padding-right: 0;

}

.yxxrui-slider .slider-indicate-dots{

  line-height: 0;

  z-index:9999;

  margin-top: -14px;

  padding-bottom: 8px;

  position: relative;

  text-align:center;

}

.yxxrui-slider .slider-indicate-dot{

  width:6px;

  height:6px;

  background:rgba(255, 255, 255, 0.5);

  display:inline-block;

  margin-right:4px;

  border-radius:100%;

  line-height: 0;

  box-sizing: border-box;

}

.yxxrui-slider .button-hover{

  background: none;

}

.yxxrui-slider .slider-indicate-dot.active{

  background: white;

  width:16px;

  border-radius:4px;

}


js

var myslider = require('../../utils/yxxrui.slider.js');

//index.js

//获取应用实例

const app = getApp();

Page({

  data: {

    indicatorDots: false,

    autoplay: false,

    interval: 5000,

    duration: 1000,

    curPage:1,

    x: 0

  },

  onLoad:function(){

    myslider.initMySlider({

      that:this,

      datas: [

        '../../img/1.jpg',

        '../../img/2.jpg',

        '../../img/3.jpg',

        '../../img/4.jpg'

      ],

      // autoRun:true,

      blankWidth : 12,

      newImgWidth: 18,

      interval:1500,

      duration:200,

      direction:'left',

      startSlide:function(curPage){


      },

      endSlide: function (curPage){


      }

    });

  }

})


yxxrui.slider.js

var debug = getApp().debug || true;

//此处数据初始化后就不修改了

// var yxxruiSliderData = {

//  datas: [],//数据包,必须为数组

//  indicateDots: [],

//  blankWidth: 12,

//  newImgWidth: 18,

//  totalWidth:0,

//  firstX:0, 

//  direction:'left',

//  autorun:true,

//  duration:1000,

//  interval:2000,

//  startSlideCallback:null,

//  endSlideCallback:null

// };

//暂时记录一下,经常修改的参数

// var yxxruiSliderX;//当前位移的x

// var yxxruiSliderLock;//滚动锁

// var yxxruiSliderFirstPointX;//第一次触摸时的x坐标

// var yxxruiAutoRunTimer=null;//自动滚动定时器

// var yxxruiSlideTimer= null;//滚动一屏的定时器

// var yxxruiCurPage=1;//当前页面

// var yxxruiSliderLastX;//触摸屏幕时的位移x

function initMySlider(opt) {

  if(opt.that==null){

    console.log('请传入正确的this');

    return;

  }

  var that = opt.that;

  //此处数据初始化后就不修改了

  var yxxruiSliderData = {};

  //数据包,必须为数组

  yxxruiSliderData.datas = opt.datas || [];

  //空白处的宽度

  yxxruiSliderData.blankWidth = opt.blankWidth==undefined? 12:opt.blankWidth;

  //新图片凸出来的宽度

  yxxruiSliderData.newImgWidth = opt.newImgWidth == undefined ? 18 : opt.newImgWidth;

  //是否自动滚动

  yxxruiSliderData.autoRun = opt.autoRun;

  //每隔x毫秒滚动一次

  yxxruiSliderData.interval = opt.interval || 3000;

  //滚动一次需要x秒

  yxxruiSliderData.duration = opt.duration || 200;

  //滚动方向

  yxxruiSliderData.direction = opt.direction || 'left';

  //滚动开始回调事件

  yxxruiSliderData.startSlideCallback = opt.startSlide;

  //滚动结束回调事件

  yxxruiSliderData.endSlideCallback = opt.endSlide;

  var len = yxxruiSliderData.datas.length;

  if (len < 1) {

    console.log('数据数组必须设置');

    return;

  }

  //轮播图底部小点

  yxxruiSliderData.indicateDots = [];

  for(var i=0;i<len;i++){

    yxxruiSliderData.indicateDots.push(i+1);

  }

  //处理数据

  var fistImg = yxxruiSliderData.datas[0];

  var lastImg = yxxruiSliderData.datas[len - 1];

  yxxruiSliderData.datas.unshift(lastImg);//将最后一张图片重复放到前边,做无缝滚动

  yxxruiSliderData.datas.push(fistImg);//将第一张图片重复放到后边,做无缝滚动


  //计算各种参数

  var w = wx.getSystemInfoSync().screenWidth;

  var kx = yxxruiSliderData.blankWidth;//白色空隙宽度12px

  var nx = yxxruiSliderData.newImgWidth;//新图片突出来18px

  var ox = kx + nx * 2;//每页中无效的宽度

  var fx = w - (ox + nx);

  //总宽度

  yxxruiSliderData.totalWidth = yxxruiSliderData.datas.length * (w-ox);

  yxxruiSliderData.firstX = -fx;

  that.setData({

    yxxruiSliderData: yxxruiSliderData,

    yxxruiSliderX: yxxruiSliderData.firstX,

    yxxruiSliderCurPage : 1

  });

  dealEvent(that);

  // if (autoRun) {

  //  autoRunMyslider(that, interval);

  // }

  yxxruiSliderData.startSlideCallback && yxxruiSliderData.startSlideCallback(1);

  yxxruiSliderData.endSlideCallback && yxxruiSliderData.endSlideCallback(1);

}

function dealEvent(that) {

  //触摸开始事件

  that.sliderTouchStart = function (opt) {

    //解锁

    that.data.yxxruiSliderLock = 0;

    //让当前滚动暂定

    that.data.yxxruiSlideTimer && clearInterval(that.data.yxxruiSlideTimer);

    //暂定自动滚动

    that.data.yxxruiAutoRunTimer && clearInterval(that.data.yxxruiAutoRunTimer);

    that.setData({

      yxxruiSliderLastX : that.data.yxxruiSliderX,

      yxxruiSliderFirstPointX: opt.touches[0].clientX,

      yxxruiSlideTimer:null,

      yxxruiAutoRunTimer:null

    });

  };

  //触摸移动事件

  that.sliderTouchMove = function (opt) {

    //让轮播图跟着指头滑动

    var pointx = opt.touches[0].clientX;

    var x = that.data.yxxruiSliderLastX + (pointx - that.data.yxxruiSliderFirstPointX);

    that.setData({

      yxxruiSliderX: x

    });

  };

  //触摸结束事件

  that.sliderTouchEnd = function (opt) {

    //结束后,让轮播图回到该回到的地方

    slidePage(that, 0);

    //继续开启自动滚动

    var mydata = that.data.yxxruiSliderData;

    if (mydata.autoRun) {

      autoRunMyslider(that, mydata.interval);

    }

  };

  //触摸取消事件跟触摸结束事件相同

  that.sliderTouchCancel = that.sliderTouchEnd;

  //记录用户设置的隐藏事件,等待执行完毕之后恢复此事件

  var oldHide = that.onHide;

  that.onHide =function(){

    that.data.yxxruiAutoRunTimer && clearInterval(that.data.yxxruiAutoRunTimer);

    that.setData({

      yxxruiAutoRunTimer: null

    });

    oldHide && oldHide();

  };

  //记录用户设置的显示事件,等待执行完毕之后恢复此事件

  var oldShow = that.onShow;

  that.onShow = function(){

    var mydata = that.data.yxxruiSliderData;

    if (mydata.autoRun) {

      autoRunMyslider(that, mydata.interval);

    }

    oldShow && oldShow();

  }

}

/**

* 自动开始滚动

*/

function autoRunMyslider(that, t) {

  that.data.yxxruiAutoRunTimer && clearInterval(that.data.yxxruiAutoRunTimer);

  var autoRunTimer = setInterval(function () {

    var dir = that.data.yxxruiSliderData.direction=='right'?1:-1;

    slidePage(that, dir);

  }, t);

  that.setData({

    yxxruiAutoRunTimer: autoRunTimer

  });

}

//一次性滚动一屏,并且有方向

function slidePage(that,page){

  var mydata = that.data.yxxruiSliderData;

  var lastx = that.data.yxxruiSliderX - mydata.newImgWidth;

  var perScreenX = mydata.totalWidth / mydata.datas.length;

  var remain = (perScreenX-Math.abs(lastx%perScreenX))%perScreenX;//看看当前剩余了多少

  if(remain>0){

    //只需要看看离那边近就跑那边

    if(remain<perScreenX/2){

      //说明距离左边近

      slideTo(that, -remain);

    }else{

      //说明右边近

      slideTo(that,perScreenX-remain);

    }

  }else{

    slideTo(that, perScreenX * page);

  }

}

function slideTo(that, x) {

  //锁,如果正在滚动,那么不允许操作

  if (that.data.yxxruiSliderLock == 1) return;

  that.setData({

    yxxruiSliderLock:1

  });


  var mydata = that.data.yxxruiSliderData;

  var i = 0;

  var timeStep = 20;//x毫秒刷新一次

  var lastx = that.data.yxxruiSliderX;

  var perScreenX = mydata.totalWidth / mydata.datas.length;

  var step = Math.floor(perScreenX / (mydata.duration / timeStep));

  var totalWidth = mydata.totalWidth;


  var slideTimer = setInterval(function () {

    if(i==0){

      mydata.startSlideCallback && mydata.startSlideCallback(that.data.yxxruiSliderCurPage);

    }

    if (i >= Math.abs(x)) {

      slideTimer && clearInterval(slideTimer);

      that.setData({

        yxxruiSlideTimer:null

      });

      if (lastx + x >= mydata.newImgWidth) {

        //滚动到边际,处理无缝滚动

        var nowx = mydata.newImgWidth - (totalWidth - perScreenX * 2);

        that.setData({

          yxxruiSliderX: nowx

        });

      }

      if (lastx + x + totalWidth - perScreenX <= mydata.newImgWidth) {

        that.setData({

          yxxruiSliderX: mydata.firstX

        });

      }

      lastx = that.data.yxxruiSliderX;

      var curPage = Math.abs(Math.floor((lastx + perScreenX) / perScreenX))+1;

      that.setData({

        yxxruiSliderCurPage:curPage

      });

      mydata.endSlideCallback && mydata.endSlideCallback(curPage);

      that.setData({

        yxxruiSliderLock: 0

      });

      return;

    }

    //如果距离 比步数大,那么直接跳步数,不够的话,直接变成最终的答案

    if (Math.abs(x) - i > step) {

      i += step;

    } else {

      i = Math.abs(x);

    }

    if (x > 0) {

      that.setData({

        yxxruiSliderX: lastx + i

      });

    } else {

      that.setData({

        yxxruiSliderX: lastx - i

      });

    }

  }, timeStep);

  that.setData({

    yxxruiSlideTimer: slideTimer

  });

}

module.exports = {

  initMySlider: initMySlider

};


原文链接:https://www.cnblogs.com/yxxrui/p/wechatDiySlider.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容