完整代码: 其实主要也就是记录touch的clienY做一个处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>
移动端 Touch 滑动反弹
</title>
<style>
/* 样式初始化 */
* {
margin: 0;
padding: 0;
}
html,body {
width: 100%;
height: 100%;
}
aside {
height: 100%;
width: 100%;
background: salmon;
}
/* 列表的父盒子,限制宽高 */
/* 注意设置overflow: hidden;样式后,超出这个盒子的ul将不会显示 */
.draw {
width: 100%;
height: 600px;
/* border: 2px solid #ccc; */
overflow: hidden;
position: fixed;
left: 0;
top: 0;
/* transform: translateY(-50%); */
}
/* li 设置了浮动, 所以 ul 要清除浮动 */
ul:after {
content: "";
display: block;
visibility: hidden;
height: 0;
clear: both;
}
ul {
zoom: 1;
}
li {
list-style: none;
/* float: left; */
width:100%;
height: 60px;
line-height: 60px;
text-align: center;
}
</style>
</head>
<aside class="main">
<div class="draw" id="draw">
<ul>
<li style='margin-top:-60px' id="upRefresh">加载中...</li>
<li style="background:blue">
列表一
</li>
<li style="background:yellowgreen">
列表二
</li>
<li style="background:yellow">
列表三
</li>
<li style="background:cyan">
列表四
</li>
<li style="background:orangered">
列表五
</li>
<li style="background:pink">
列表六
</li>
<li style="background:red">
列表七
</li>
<li style="background:purple">
列表八
</li>
<li style="background:violet">
列表九
</li>
<li style="background:brown">
列表十
</li>
<li style="background:green">加载中...</li>
</ul>
</div>
</aside>
<body>
<script>
var draw = document.querySelector('#draw');
var upR = document.querySelector('#upRefresh');
var ul = draw.children[0];
var startY = 0;// 刚触碰到屏幕的时的手指信息
var centerY = 0;// 用来记录每次触摸时上一次的偏移距离
var maxDown = 60;// 设定一个最大向下滑动的距离
var loadingH = 60;
var maxUp = -(ul.offsetHeight - draw.offsetHeight-loadingH);// 求得一个最大向上滑动的距离 60
var maxUpBounce = 0;// 向上反弹值
var maxDownBounce = 0//-(ul.offsetHeight - draw.offsetHeight);// 向下反弹值
// touchstart 时,记录手指在 Y 轴上的落点距离可视顶部距离
ul.addEventListener('touchstart', function (e) {
startY = e.changedTouches[0].clientY;
})
// touchmove 时,记录此时手指在 Y 轴上的落点距离可视顶部距离
ul.addEventListener('touchmove', function (e) { // 清除过渡
ul.style.transition = 'none';
// 获取差值
var dy = e.changedTouches[0].clientY - startY;
// 上次的滑动距离加上本次的滑动距离
var tempY = centerY + dy;
// 当上次滑动的距离加上本次滑动的距离 大于 设定的最大向下距离的时候
if (tempY > maxDown) {
tempY = maxDown;
upR.innerHTML = '松手刷新'
}// 当上次滑动的距离加上本次滑动的距离 小于 设定的最大向上距离的时候
else if (tempY < maxUp) {
tempY = maxUp;
}
// 设置 ul 在 Y 轴上的偏移
ul.style.transform = 'translateY(' + tempY + 'px)';
})
// touchend 时,记录此时手指在 Y 轴上的落点距离可视顶部距离
ul.addEventListener('touchend', function (e) {
upR.innerHTML = '加载中'
// 获取差值
var dy = e.changedTouches[0].clientY - startY;
// 记录移动的距离
centerY = centerY + dy;// 两次滑动的距离 大于 设定的 向上 反弹值时
if (centerY > maxUpBounce) {
// 让两次滑动的距离 等于 设置的值
centerY = maxUpBounce;
// 添加过渡
setTimeout(()=>{
//fecth之类的,完成之后再弹回
ul.style.transition = 'transform .5s';
ul.style.transform = 'translateY(' + centerY + 'px)';
},1000)
}
// 两次滑动的距离 小于 设定的 向下 反弹值时
else if (centerY < maxDownBounce) {
// 让两次滑动的距离 等于 设置的值
centerY = maxDownBounce;
// 添加过渡
setTimeout(()=>{
ul.style.transition = 'transform .5s';
ul.style.transform = 'translateY(' + centerY + 'px)';
},500)
}
})
</script>
</body>
</html>