微信小程序自定义轮播图

实现效果

在这里插入图片描述

在这里插入图片描述

wxml:

<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>

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值