效果示例图
示例代码
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <meta name="viewport" content="width=device-width,initial-scale=1.0" />
- <title></title>
- <style type="text/css">
- * {
- padding: 0;
- margin: 0;
- box-sizing: border-box;
- }
- .main {
- width: 100%;
- height: 100vh;
- background-color: #f5f5f5;
- position: relative;
- }
- .dot-wrap {
- width: 100%;
- height: 30px;
- position: absolute;
- background-color: #fff;
- top: -30px;
- }
- .dot {
- position: absolute;
- width: 10px;
- height: 10px;
- border-radius: 10px;
- background-color: rgb(0, 0, 0, 0.3);
- top: 0;
- left: 50%;
- margin-left: -5px;
- }
- .dot:last-child {
- display: none;
- }
- .dot.loading {
- display: unset;
- animation: dot-move 1.5s infinite;
- }
- @keyframes dot-move {
- 0% {
- transform: translateX(-20px);
- }
- 33.33% {
- transform: translateX(-20px);
- }
- 33.34% {
- transform: translateX(0px);
- }
- 66.66% {
- transform: translateX(0px);
- }
- 66.67% {
- transform: translateX(20px);
- }
- 100% {
- transform: translateX(20px);
- }
- }
- .block-item {
- width: 100%;
- height: 200px;
- background-color: red;
- margin-bottom: 12px;
- }
- </style>
- </head>
- <body>
- <div class="main">
- <div class="dot-wrap">
- <div class="dot"></div>
- <div class="dot"></div>
- <div class="dot"></div>
- <div class="dot"></div>
- </div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- <div class="block-item"></div>
- </div>
- </body>
- <script type="text/javascript">
- let timerHandle = null;
- const mainDom = document.querySelector(".main");
- const dots = document.querySelectorAll(".dot");
- const rootDocument = document.documentElement;
- //当滚动条在最顶部时可以下拉刷新
- if (rootDocument.scrollTop === 0) {
- addTouchEvent();
- }
- //滚动监听
- window.onscroll = function() {
- //当滚动条到达顶部时,可以触发下拉拖动事件
- if (rootDocument.scrollTop <= 0) {
- rootDocument.scrollTop = 0;
- addTouchEvent();
- } else {
- removeTouchEvent();
- }
- }
- let distance, ox, oy, x, y = 0;
- function startEvent(e) {
- console.log("[start]", e)
- //获取手指起始值
- ox = e.touches[0].clientX;
- oy = e.touches[0].clientY;
- }
- function moveEvent(e) {
- if (!e.cancelable) {
- return; // 如果事件不可取消,直接返回,避免报错
- }
- //获取手指移动值
- x = e.touches[0].clientX;
- y = e.touches[0].clientY;
- //判断下拉意图
- if (y - oy > 0) {
- const deg = Math.atan(Math.abs(x - ox) / Math.abs(y - oy)) / Math.PI * 180;
- if (deg > 40) {
- ox = x;
- oy = y;
- return false;
- }
- } else {
- removeTouchEvent();
- if (rootDocument.scrollTop === 0) {
- addTouchEvent();
- return false;
- }
- }
- //手指移动的距离
- distance = y - oy;
- //添加阻尼效果
- let percent = (100 - distance * 0.5) / 100;
- percent = percent < 0.5 ? 0.5 : percent;
- distance = distance * percent
- //设置页面偏移距离
- mainDom.style.transform = `translateY(${distance}px)`
- console.log("[move]", distance)
- if (distance > 20 && distance <= 50) {
- dots[0].style.transform = `translateX(-${(distance-20)*2/3}px)`;
- dots[2].style.transform = `translateX(${(distance-20)*2/3}px)`;
- } else if (distance > 50) {
- dots[0].style.transform = `translateX(-20px)`;
- dots[2].style.transform = `translateX(20px)`;
- }
- e.preventDefault();
- }
- function endEvent() {
- //当拖动的相对值大于50时
- if (distance >= 50) {
- //可以触发下拉刷新
- dots[3].classList.add('loading')
- mainDom.style.transition = `all 0.2s`;
- mainDom.style.transform = `translateY(50px)`
- if (timerHandle) {
- clearTimeout(timerHandle)
- }
- timerHandle = setTimeout(() => {
- if (timerHandle) {
- clearTimeout(timerHandle)
- }
- removeEffect()
- }, 2000);
- } else {
- removeEffect()
- }
- }
- function removeEffect() {
- //清除过渡效果
- mainDom.style.transition = `all 0.2s`;
- mainDom.style = '';
- dots[3].classList.remove('loading')
- }
- function addTouchEvent() {
- /**
- * 通过将`passive`设置为`false`,表示在触发`touchmove`事件时,事件处理函数可以调用`preventDefault()`来阻止默认行为。
- * 这意味着在移动过程中,可以阻止浏览器执行默认的滚动行为。
- */
- mainDom.addEventListener('touchstart', startEvent, {
- passive: false
- });
- mainDom.addEventListener("touchmove", moveEvent, {
- passive: false
- })
- mainDom.addEventListener('touchend', endEvent, {
- passive: false
- })
- }
- function removeTouchEvent() {
- mainDom.removeEventListener('touchstart', startEvent);
- mainDom.removeEventListener("touchmove", moveEvent)
- mainDom.removeEventListener('touchend', endEvent)
- }
- </script>
- </html>
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |