前端模仿swiper构造弹性布局的插件,支持下滑刷新

本文介绍了一款自定义的移动端Swiper插件,该插件实现了下滑刷新功能,通过touchstart、touchmove和touchend事件实现手势滑动,同时优化了UI效果,包括底部元素透明度和图标旋转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:自己在公司开发移动端的时候,发现swiper的触发函数中好像没有能实现下滑刷新,触发自定义事件的功能,在网上搜索了之后也没有很好demo,决定自己写一个插件,以便以后能实现复用,减少以后的开发时间。在开发过程中自己也学习了很多原生js的东西,发现不依赖jquery和zepto其实也蛮好的,减少了依赖程度。最开始写的时候在想是不是能用scrollTop来实现这个功能,后来才发现本就是应该使用css的transform属性的translate来实现的比较好一些。废话说了这么多,进入正题吧。

  • 首先先把架子打好,html加css把这个滑动组件的使用场景写好,就有了如下的demo

在pc端开发移动端的h5页面注意的就是px的像素转换啊,mate设置等,这些在代码里面都有了,我这把就不赘述了。

  • 接下来就是考虑如何解决在移动端实现按住屏幕手势滑动,屏幕跟着滑动的问题了

其实现在我们pc端发开的时候,就是一个鼠标点击事件的问题,这里就涉及了js的原生事件,touchstart,touchmove,touchend这三个重要的函数了。简单来说,其实就是在按住的时候,记录下鼠标点击(touchstart)时候的pageY,在鼠标移动(touchmove)的是时候一直记录下此刻的pageY的值,并且根据这个时候pageY值与鼠标点击(touchstart)的时候的差值来设定dom的transform,这样就实现了在不在滚动条滚动范围内实现手势滑动,dom内容也随着滚动,贴上代码(其实要考虑一下滚动内容在容器内的正常情况,这个情况可以用内部dom的高度减去外部容器的高度和外部容器的scrollTop来判断)

function touchStart(e){
    startY = e.touches[0].pageY;
    num=1;
}
function touchMove(e){
	if(_parent.scrollTop>0&&_parent.scrollTop<Difference){
		//考虑两个边界的移动情况
		startY = e.touches[0].pageY;
	}else{
		moveY = (e.touches[0].pageY - startY)/2;
		var opa = -moveY/singleH;
		if(Difference>0){
			document.getElementById('bottomtab').style.opacity = opa;
			document.getElementById('rotate').style.transform = 'rotate('+opa*180+'deg)';
		}
		_son.style.transform = "translate(0px,"+moveY+"px)";
	}
}

我这边还加上了在移动的时候对于底部元素的透明度和图标rotate的设置,优化一下ui

  • 下面介绍一下当我们的手离开屏幕,也就是鼠标松开之后的事件。

当我们滑动的时候,滚动条已经达到边界值,无法支持内部dom继续滚动,在touchmove中我们已经定了函数,支持内容随着我们的手势弹性移动,那么松开的时候如何让他返回他原本改在的边界值呢,其实很简单。只要用一个计时器去让他自己返回去就可以了。涉及的内容就是判断之前的tranform的值是什么样的就可以了(我这把因为在底部加了一个不占位置的css为position:absolute的元素所以要多加一个计时器防止有时候的bug出现。这部分多加的内容其实就是为了显示提示刷新的那些内容,为了更好ui~),贴上代码。

function touchEnd(e){
	if(_parent.scrollTop>0&&_parent.scrollTop<Difference){

	}else{
		if(-moveY>(1/2*singleH)&&Difference>0){
			refresh();
		}
		var tick = setInterval(function(){
			if(moveY>=0)
				moveY = moveY-adjust(num)<0?0:moveY-adjust(num);
			else{
				moveY = moveY+adjust(num)>0?0:moveY+adjust(num);
			}
		     _son.style.transform = "translate(0px,"+moveY+"px)";
	        if(moveY==0||moveY==singleH){
	            clearInterval(tick);
	            var sub = setInterval(function(){
	            	if(_parent.scrollTop>Difference){
	            		_parent.scrollTop--;
	            	}else{
	            		clearInterval(sub);
	            	}
	            },clock)
	        }
		},clock)
	}
}

其实看完了这些,大家是不是对我这函数里面很多参数感到云里雾里,因为我再上文中没有很好的介绍清楚哈,我补在文末一下。

//保存点击时候的pageY
var startY = 0;
//保存移动时候的pageY
var moveY = 0;
//设置弹性变量,为了让回到初始位置的时候是一个越来越快的速度
var num = 1;
//调整滑动速度,越大越慢
var aJ = 100;
//调整计时器速度,越大越慢
var clock = 5;
//设置容器内外差
var Difference = 0;
//定义父级dom元素
var _parent = [];
//定义内部滚动的实际内容
var _son = [];
//定义内部滚动内容的每一个节点的高度
var singleH = 0;

//dom就是外部容器,clocktime设置滚动速度
function Elastic(dom,clocktime){
	clock = clocktime;
	_parent = dom;
	_son = dom.children[0];
	//设置容器内外差
	Difference = _son.offsetHeight-dom.offsetHeight;
	if(Difference>0){
		//超出容器时候,设置尾部节点,作为刷新提示部分
		var node=document.createElement("li");
		var textnode=document.createTextNode("");
		node.setAttribute('id',"bottomtab");
		node.innerHTML = "<i id='rotate'></i><span>释放刷新</span>";
		node.appendChild(textnode);
		dom.children[0].append(node);
		Difference = _son.offsetHeight-dom.offsetHeight;
	}
	//单个子节点的高度
	singleH = dom.children[0].children[0].offsetHeight;
	
	_son.addEventListener('touchstart',touchStart,false);
    _son.addEventListener('touchmove',touchMove,false);
    _son.addEventListener('touchend',touchEnd,false);

}
function adjust(param){
	num++;
	return (param++/aJ)
}

这些就是外部插件js里面的所有内容了,如果需要另外引用的话,只需要在html页面定义一下引用函数和刷新事件函数就可以了。另外就是自己定义一下css样式就可以了,总体来说,引用的话不是很麻烦。可能其中还存在一些bug,烦请大家指出谢谢~

如果有需要demo,可以点击这里下载,感谢大家支持

https://github.com/lisinw51/swiper-tragger

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值