效果图:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title></title> <style> .page { width: 200px; height: 400px; background: #f7f7f7; overflow: hidden; } .content { padding: 20px; margin: 0 20px; } li { padding: 20px; height: 20px; margin: 10px; background: white; } .refresh-loading { transition: all 300ms ease 0s; height: 0; padding-top: 10px; overflow: hidden; } .refresh-loading .g-m--c { width: 16px; height: 16px; border-radius: 50%; -webkit-animation-name: locate-loading; -moz-animation-name: locate-loading; animation-name: locate-loading; -webkit-animation-duration: 1.58s; -moz-animation-duration: 1.58s; animation-duration: 1.58s; -webkit-animation-timing-function: linear; -moz-animation-timing-function: linear; animation-timing-function: linear; -webkit-animation-iteration-count: infinite; -moz-animation-iteration-count: infinite; animation-iteration-count: infinite; border-top: 2px solid #f43939; border-left: 2px solid #df5555; margin: auto; } @keyframes locate-loading { 0% { opacity: 1; -webkit-transform: rotate(0deg); -moz-transform: rotate(0deg); transform: rotate(0deg); } 100% { opacity: 1; -webkit-transform: rotate(360deg); -moz-transform: rotate(360deg); transform: rotate(360deg); } } @-webkit-keyframes locate-loading { 0% { opacity: 1; -webkit-transform: rotate(0deg); -moz-transform: rotate(0deg); transform: rotate(0deg); } 100% { opacity: 1; -webkit-transform: rotate(360deg); -moz-transform: rotate(360deg); transform: rotate(360deg); } } @-moz-keyframes locate-loading { 0% { opacity: 1; -webkit-transform: rotate(0deg); -moz-transform: rotate(0deg); transform: rotate(0deg); } 100% { opacity: 1; -webkit-transform: rotate(360deg); -moz-transform: rotate(360deg); transform: rotate(360deg); } } .refresh-txt { color: #999; text-align: center; font-size: 12px; } </style> </head> <body> <div class="page"> <div class="refresh-loading"> <div class="g-m--c"></div> <p class="refresh-txt">下拉可刷新</p> </div> <ul class="content"> <li>t条目1</li> <li>t条目1</li> <li>t条目1</li> <li>t条目1</li> </ul> </div> </body> <script> var moveEle = document.getElementsByClassName('content')[0]; //内容 var refreshEle = document.getElementsByClassName('refresh-loading')[0]; //刷新的loading var refreshTxtEle = document.getElementsByClassName('refresh-txt')[0]; //刷新显示的提示文字 var touch, moved, startY, diff, moveDiff = 60, pagePull = true; moveEle.addEventListener('touchstart', function (e) { if (window.scrollY > 0) { //当页面已经有滚动或者不是置顶的时候,不需要进行下拉刷新,是页面正常的滑动 touch = false; return; } touch = true; //触摸开始 moved = false; //还没有进行下拉刷新的滑动 startY = e.touches[0].clientY; //记录当前手指在屏幕上的纵向坐标,用于判断页面是上滑还是下滑 }, false); moveEle.addEventListener('touchmove', function (e) { if (!touch || !pagePull) { return; } var touchesDiff = e.touches[0].clientY - startY; //计算的移动位移 if (touchesDiff < 0) { //说明页面是向上滑的,不做任何操作 moved = false; return; } moved = true; diff = touchesDiff; var distance = 0; if (diff <= moveDiff) { //moveDiff至少要等于loading的高度 //当滑动小于规定的临界值时 distance = diff; refreshTxtEle.innerHTML = '下拉可刷新'; } else { refreshTxtEle.innerHTML = '释放可刷新'; //弹性 if (touchesDiff <= (2 * moveDiff)) { distance = moveDiff + 0.5 * (touchesDiff - moveDiff); } else { distance = moveDiff + 0.1 * (touchesDiff - moveDiff) + 0.05 * (touchesDiff - 2 * moveDiff); } } if (distance > 0) { //滑动的距离 css(refreshEle, 0); refreshEle.style.height = distance + 'px'; } }, false); moveEle.addEventListener('touchend', function (e) { if (!touch || !moved) { refreshEle.style.height = '0px'; return; } css(refreshEle, 300); pagePull = false; if (diff > moveDiff) { refreshTxtEle.innerHTML = '刷新中'; refreshEle.style.height = moveDiff + 'px'; setTimeout(() => { //延迟模拟接口调用 css(refreshEle, 300); refreshEle.style.height = '0px'; setTimeout(() => { pagePull = true; //控制在刷新期间,重复向下拉动,不做任何操作 }, 300); }, 500); } else { pagePull = true; refreshEle.style.height = '0px'; } }, false); function css(ele, t) { ele.style.transition = "all " + t + "ms"; ele.style.webkitTransition = "all " + t + "ms"; } </script> </html>