5.2解决:导航栏移动的时候也会点击的问题;红色标记为新增;
1 / 4.1导航可以拖动 2 (function () { 3 var nav = document.querySelector('#nav'); 4 var ul = nav.querySelector('#nav ul'); 5 var navItems = ul.querySelectorAll('li'); 6 var isTouchMove = false ; //表示是否在触摸移动; 7 8 //手指点击 9 nav.addEventListener('touchstart', function (event) { 10 ul.style.transition = 'none'; 11 var touch = event.changedTouches[0]; 12 this.startX = touch.clientX; 13 this.eleX = transformCss(ul, 'translateX'); 14 this.startTime = (new Date).getTime(); 15 this.dstX = 0; 16 // 17 isTouchMove = false; //标记还没有触摸移动 18 }); 19 20 //手指移动 21 nav.addEventListener('touchmove', function (event) { 22 var touch = event.changedTouches[0]; 23 var endX = touch.clientX; 24 this.dstX = endX - this.startX; 25 var translateX = this.eleX + this.dstX; 26 // 位置限定 ;4.2橡皮筋(加速);(原理:在touchmove时判断临界值,并使用一定比例:空白宽/视口宽) 27 if (translateX > 0) { 28 var scale = 1 - translateX / (nav.clientWidth * 2) 29 translateX *= scale; 30 transformCss(ul, 'translateX', translateX); 31 } else if (translateX < nav.clientWidth - ul.offsetWidth) { 32 var rightX = nav.clientWidth - (ul.offsetWidth + translateX) 33 var scale = 1 - rightX / (nav.clientWidth * 2); 34 // 让间距乘上比例,实现间距的增大放缓 35 rightX *= scale; 36 translateX = (nav.clientWidth - rightX) - ul.offsetWidth; 37 } 38 // 设置ul 的位置 39 transformCss(ul, 'translateX', translateX); 40 41 // 标记正在触摸移动; 42 isTouchMove = true; 43 }) 44 45 // 手指离开; 实现回弹和点击 46 nav.addEventListener('touchend', function (event) { 47 var endTime = (new Date).getTime(); 48 var dstTime = endTime - this.startTime; 49 var speed = this.dstX / dstTime * 200; //因为this.dstX自带正负所以,自动判断方向; 因为分母是按毫秒计算的,所以很大 50 var translateX = transformCss(ul, 'translateX') 51 translateX += speed; 52 53 // 设置贝塞尔; 54 var besier = ''; 55 // 4.3判断临界点,实现回弹; 56 if (translateX > 0) { 57 translateX = 0; 58 besier = ' cubic-bezier(0.08, 1.44, 0.6, 1.46)'; 59 } else if (translateX < nav.clientWidth - ul.offsetWidth) { 60 translateX = nav.clientWidth - ul.offsetWidth; 61 besier = ' cubic-bezier(0.08, 1.44, 0.6, 1.46)'; 62 } 63 // 加过渡; 64 ul.style.transition = 'transform .5s' + besier; 65 transformCss(ul, 'translateX', translateX); 66 67 //5.导航可以点击 68 navItems.forEach(function(navItem){ 69 // 给所有的li添加触摸事件; 70 navItem.addEventListener('touchend',function(){ 71 if(isTouchMove){ 72 return ; 73 } 74 console.log(123) 75 // 其他所有li取消高亮; 76 navItems.forEach(function(navItem){ 77 navItem.classList.remove('active') 78 }); 79 this.classList.add('active') 80 }) 81 }) 82 }) 83 })();
选项卡:
1.选项卡滑动;
1 // 选项卡滑动 2 (function(){ 3 var tab = document.querySelector('.tab'); 4 var tabContent = tab.querySelector('.tab-content'); 5 var contentList = tab.querySelector('content-list') 6 7 // 手指触摸 8 tabContent.addEventListener('touchstart',function(event){ 9 var touch = event.changedTouches[0]; 10 this.startX = touch.clientX; 11 this.eleX = transformCss(tabContent,'translateX') 12 }); 13 //手指移动 14 tabContent.addEventListener('touchmove',function(event){ 15 var touch = event.changedTouches[0]; 16 var endX = touch.clientX; 17 var dstX = endX - this.startX ; 18 var translateX = this.eleX + dstX 19 transformCss(tabContent,'translateX',translateX); 20 }) 21 })() 22 </script>
2.选项卡切换
1 <script> 2 // 1.选项卡滑动 3 (function () { 4 var tab = document.querySelector('.tab'); 5 var tabContent = tab.querySelector('.tab-content'); 6 var contentList = tab.querySelector('.content-list'); 7 8 // 获取tab-loading 和 content-list的宽度 9 var itemWidth = contentList.offsetWidth; 10 11 // 2.让整个tabContent位移一个宽度,让ul始终在视口位置; 12 transformCss(tabContent, 'translateX', -itemWidth); 13 14 // 手指触摸 15 contentList.addEventListener('touchstart', function (event) { 16 var touch = event.changedTouches[0]; 17 this.startX = touch.clientX; 18 this.eleX = transformCss(tabContent, 'translateX'); 19 // 取消过渡 20 tabContent.style.transition = 'none'; 21 // 清零dtsX ; 避免bug ; 22 this.dstX = 0; 23 }); 24 25 //手指移动 防止tab-loading能够被拖地,所以给ul监听 26 contentList.addEventListener('touchmove', function (event) { 27 var touch = event.changedTouches[0]; 28 var endX = touch.clientX; 29 this.dstX = endX - this.startX; 30 // 计算位移的位置; 31 var translateX = this.eleX + this.dstX 32 // 3.判断临界值;超过视口一半就切换为loading图; 给tab设置了宽度,所以会比视口小 ;切换前一个0;最后一个两倍的tab宽度; 33 if (Math.abs(this.dstX) > tab.clientWidth / 2) { 34 // 判断方向: 35 if (this.dstX > 0) { //从左到右滑:切换上一张,显示前一个loading 36 translateX = 0; 37 } else if (this.dstX < 0) { //从右到左切换下一张;显示后一个loading 38 translateX = -itemWidth * 2; 39 } 40 tabContent.style.transition = 'transform .5s'; //设置位置前添加过渡 41 } 42 // 设置位置; 43 transformCss(tabContent, 'translateX', translateX); 44 }) 45 46 // 触摸结束; 4.滑动没超过一半,显示内容区域; 47 contentList.addEventListener('touchend', function (event) { 48 var touch = event.changedTouches[0]; 49 // 获取当前滑动位置; 50 if (Math.abs(this.dstX) <= tab.clientWidth / 2) { 51 tabContent.style.transition = 'transform .5s'; //设置位置前添加过渡 52 // 回到内容区域 53 transformCss(tabContent, 'translateX', -itemWidth); 54 } 55 }) 56 })() 57 </script>
3.loading图优化
1 <script> 2 // 选项卡滑动 3 (function () { 4 var tab = document.querySelector('.tab'); 5 var tabContent = tab.querySelector('.tab-content'); 6 var contentList = tab.querySelector('.content-list'); 7 var tabLoadings = tab.querySelectorAll('.tab-loading') 8 9 // 获取tab-loading 和 content-list的宽度 10 var itemWidth = contentList.offsetWidth; 11 12 // 让整个tabContent位移一个宽度,让ul始终在视口位置; 13 transformCss(tabContent, 'translateX', -itemWidth); 14 15 // 手指触摸 16 contentList.addEventListener('touchstart', function (event) { 17 var touch = event.changedTouches[0]; 18 this.startX = touch.clientX; 19 this.eleX = transformCss(tabContent, 'translateX'); 20 // 取消过渡 21 tabContent.style.transition = 'none'; 22 // 清零dtsX ; 避免bug ; 23 this.dstX = 0; 24 25 // 2.2 loading图点击的时候不显示;过渡完成之后显示; 26 tabLoadings.forEach(function(tabLoading){ 27 tabLoading.style.opacity = 0 ; 28 }) 29 }); 30 31 //手指移动 防止tab-loading能够被拖地,所以给ul监听 32 contentList.addEventListener('touchmove', function (event) { 33 var touch = event.changedTouches[0]; 34 var endX = touch.clientX; 35 this.dstX = endX - this.startX; 36 // 计算位移的位置; 37 var translateX = this.eleX + this.dstX 38 // 判断临界值;超过视口一半就切换为loading图; 给tab设置了宽度,所以会比视口小 ;切换前一个0;最后一个两倍的tab宽度; 39 if (Math.abs(this.dstX) > tab.clientWidth / 2) { 40 // 判断方向: 41 if (this.dstX > 0) { //从左到右滑:切换上一张,显示前一个loading 42 translateX = 0; 43 } else if (this.dstX < 0) { //从右到左切换下一张;显示后一个loading 44 translateX = -itemWidth * 2; 45 } 46 tabContent.style.transition = 'transform .5s'; //设置位置前添加过渡 47 } 48 // 设置位置; 49 transformCss(tabContent, 'translateX', translateX); 50 }); 51 52 // 触摸结束; 滑动没超过一半,显示内容区域; 53 contentList.addEventListener('touchend', function (event) { 54 var touch = event.changedTouches[0]; 55 // 获取当前滑动位置; 56 if (Math.abs(this.dstX) <= tab.clientWidth / 2) { 57 tabContent.style.transition = 'transform .5s'; //设置位置前添加过渡 58 // 回到内容区域 59 transformCss(tabContent, 'translateX', -itemWidth); 60 } 61 }) 62 63 64 //解决2.1问题: 65 tabLoadings.forEach(function(tabLoading){ 66 tabLoading.addEventListener('transitionend',function(event){ 67 event.stopPropagation(); 68 }) 69 }) 70 71 // 1.过渡结束后加载图片; 72 tabContent.addEventListener('transitionend', function () { 73 // 获取当前位置: 74 var translateX = transformCss(tabContent,'translateX'); 75 // 滑动没到一半的时候是不加载图片的; 76 if(translateX === tab.clientWidth/2){ 77 return ; 78 }; 79 80 console.log('a,过渡了') //会触发三次;因为子元素和父元素都有过渡,子元素过渡冒泡到父元素上; 81 // 2.1 tab-loading图优化 ; // loading图touchstart的时候不显示;过渡完成之后显示; 82 tabLoadings.forEach(function(tabLoading){ 83 tabLoading.style.opacity = 1 ; 84 }); //会引起过渡;冒泡到tab-content父元素上; transitionend程序会再执行一遍; 导致过渡无法生效; 85 86 setTimeout(function(){ 87 tabContent.style.transition = 'none'; 88 transformCss(tabContent, 'translateX', -itemWidth); 89 },2000) 90 }); 91 92 })(); 93 </script>
4.选项卡导航
浙公网安备 33010602011771号