js移动端菜上下滑动效果(JS实现移动端上下滑动一次一屏)
类别:编程学习 浏览量:2445
时间:2021-10-28 10:39:26 js移动端菜上下滑动效果
JS实现移动端上下滑动一次一屏本文实例为大家分享了JS实现移动端上下滑动一次一屏的具体代码,供大家参考,具体内容如下
功能如下:
- 头部: 附近、关注、推荐选项卡的切换
- 左右滑动功能、头部选项卡跟随动画
- 上下滑动划动一屏,滑动超过头部刷新
- 双击选项卡回到顶部
上代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; -moz-user-select: none; /*火狐*/ -webkit-user-select: none; /*webkit浏览器*/ -ms-user-select: none; /*IE10*/ -khtml-user-select: none; /*早期浏览器*/ user-select: none; } #box { width: 350px; height: 500px; margin: 30px auto; border-radius: 5px; box-shadow: 0px 0px 27px -3px red; -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; overflow: hidden; position: relative; background-color: #ccc; } .childbox { width: 300%; height: 100%; display: flex; position: absolute; top: 0; left: 0; } .childbox>li { flex: 1; height: 100%; } .child1 { background-color: salmon; } .child2 { background-color: greenyellow; } .child3 { background-color: blueviolet; } .nav_box { position: absolute; width: 100%; text-align: center; line-height: 50px; } .nav_box li { display: inline-block; color: #fff; margin: 0 5px; position: relative; } .active_nav::before { content: ''; position: absolute; background-color: #fff; left: 2px; bottom: 7px; width: 27px; height: 2px; } .childbox>li { position: relative; } .childbox>li .listview { width: 100%; position: absolute; } .view_child { text-align: center; line-height: 200px; color: #fff; font-size: 25px; } </style> </head> <body> <li id="box"> <li class="childbox"> <li class="child1"> <li class="listview" type="附近"> </li> </li> <li class="child2"> <li class="listview" type="关注"> </li> </li> <li class="child3"> <li class="listview" type="推荐"> </li> </li> </li> <li class="nav_box"> <li>附近</li> <li>关注</li> <li class="active_nav">推荐</li> </li> </li> </body> <script> //获取动画盒子 let childbox = document.querySelector('.childbox') //获取屏幕的高度 let viewheight = document.querySelector('#box').offsetHeight //获取所有的导航 let childnav = document.querySelector('.nav_box').querySelectorAll('li') //获取视频类型盒子 let viewlist = document.querySelectorAll('.listview') //导航索引(0,附近,1,关注,2推荐) let indextype = 2 //视频播放的索引(0:附近,1:关注,2:推荐)[下标,视频的数量,页码] let view_index = { 0: [0, 0, 1], 1: [0, 0, 1], 2: [0, 0, 1] } //初始化导航 set_nav_active(indextype) //导航选中状态 function set_nav_active(index) { //清除选中状态 for (let i = 0; i < childnav.length; i++) { childnav[i].className = '' } //给选中的加上值 childnav[index].className = 'active_nav' //改变盒子位置 childbox.style.left = index * -100 + '%' } //给导航加点击事件 for (let i = 0; i < childnav.length; i++) { childnav[i].onclick = function () { //加上过渡动画 childbox.style.transition = 'all 0.5s' //改变点击导航状态 indextype = i set_nav_active(indextype) } } //左右滑动 let box = document.querySelector('#box') //动画是否结束的状态 let transition_status = true //按下 box.onmousedown = function (event) { //判断是否可以执行动画 if (!transition_status) { return } //获取坐标值 let startY = event.clientY let startX = event.clientX //是否要进判断 let t_l_type = true //获取上下还是左右滑动的状态(0:不动;1:左右;2:上下) let move_type = 0 //记录动画行为(1:下拉,2:上下,3:左右,0:不动) let transition_type = 0 // 左右start //清除盒子动画 childbox.style.transition = '' //获取盒子left位置 let startleft = childbox.offsetLeft //是否切换滑动 let type = { a: false, b: '' } //左右over //上下滑动 //滑动的初始化位置 let startTop = viewlist[indextype].offsetTop //判断是否切换 let top_type_view = { a: false, //是否要切换 b: '', //判断向上还是向下 } console.log(startTop) //上下over //下拉刷新 //清除动画 viewlist[indextype].style.transition = ''; //记录下拉距离 let b_top = 0 //下拉over document.onmousemove = function (event) { //获取移动时坐标 let moveY = event.clientY let moveX = event.clientX //加是否要判断的开关 if (t_l_type) { //判断是左右滑动还是上下 if (Math.abs(moveY - startY) > 5) { //停止下次判断 t_l_type = false //记录滑动状态 move_type = 2 } if (Math.abs(moveX - startX) > 5) { //停止下次判断 t_l_type = false //记录滑动状态 move_type = 1 } } //判断滑动代码 if (move_type == 2) { //下拉需要两个条件 1 下拉的 2 上没有东西了 if (view_index[indextype][0] == 0 && moveY - startY > 0) { console.log('下拉') //改变动画状态 transition_type = 1 //计算下拉距离 b_top = moveY - startY //拉动视图盒子 viewlist[indextype].style.top = b_top + 'px' return } //执行上下滑动 //下拉的时候拒绝上下滑动 if (transition_type != 1) { //改变动画状态 transition_type = 2 //移动的位置 let moveY = event.clientY //计算上下移动的距离 let num = moveY - startY //改变拖拽元素的top值 viewlist[indextype].style.top = startTop + num + 'px' //判断是否要切换 if (num > 70) { top_type_view.a = true top_type_view.b = '上' } else if (num < -70) { top_type_view.a = true top_type_view.b = '下' } } } else if (move_type == 1) { // 左右的代码 //改变动画状态 transition_type = 3 //移动的位置 let moveX = event.clientX //移动的距离 let num = moveX - startX //盒子需要的left值 childbox.style.left = startleft + num + 'px' //滑动的方向 if (moveX > startX) { if (num > 100) { type.a = true type.b = '右' } } else if (moveX < startX) { if (num < -100) { type.a = true type.b = '左' } } // over } } //抬起 window.onmouseup = function () { //清除滑动事件 document.onmousemove = '' //判断执行动画 if (transition_type == 1) { //下拉 //加上动画 viewlist[indextype].style.transition = 'all .5s'; //判断拉动的距离判断是否刷新 if (b_top > 70) { //执行动画 transition_status = false viewlist[indextype].style.top = '70px' setTimeout(function () { viewlist[indextype].style.top = '0px' //从第一页开始 view_index[indextype][2] = 1 autoview(indextype) //还原动画 setTimeout(() => { transition_status = true }, 500); }, 2000) } else { viewlist[indextype].style.top = '0px' } } else if (transition_type == 2) { //上下 //加上过渡动画 viewlist[indextype].style.transition = 'all .5s'; //判断执行的动画 if (top_type_view.a) { //判断上下切换 if (top_type_view.b == '上') { //下标改变 view_index[indextype][0]-- if (view_index[indextype][0] <= -1) { view_index[indextype][0] = 0 } viewlist[indextype].style.top = view_index[indextype][0] * -viewheight + 'px' console.log('上') } else if (top_type_view.b == '下') { view_index[indextype][0]++ if (view_index[indextype][0] >= view_index[indextype][1] - 2) { //生成新的视频 autoview(indextype) } viewlist[indextype].style.top = view_index[indextype][0] * -viewheight + 'px' } } else { //还原现有状态 viewlist[indextype].style.top = startTop + 'px' } } else if (transition_type == 3) { //左右 //执行判断是否切换 if (type.a) { if (type.b === '左') { indextype++ if (indextype >= 3) { indextype = 2 } } else if (type.b === '右') { indextype-- if (indextype <= -1) { indextype = 0 } } } //加上过渡 childbox.style.transition = 'all 0.5s' //调取切换函数 set_nav_active(indextype) } //还原下次判断 t_l_type = true //还原下次状态 move_type = 0 //还原动画状态 transition_type = 0 } } //随机背景颜色 function autocolor() { return `rgb(${Math.floor(Math.random() * 255)},${Math.floor(Math.random() * 255)},${Math.floor(Math.random() * 255)})` } //默认生成视频列表 for (let i = 0; i < viewlist.length; i++) { autoview(i) } //生成视频列表 function autoview(index) { //获取视频类型 let type = viewlist[index].getAttribute('type') //更改视频数量 if (view_index[index][2] == 1) { //清除现有内容 viewlist[indextype].innerHTML = '' //记录视频数量 view_index[index][1] = 10 } else { //累加视频数量 view_index[index][1] += 10 } //index 插入的下标 for (let i = 0; i < 10; i++) { //创建dom let li = document.createElement('li') //命名 li.className = 'view_child' //内容 li.innerHTML = ` <li>${type}:${(view_index[index][2] - 1) * 10 + i + 1}</li> <hr></hr> <li>页码:${view_index[index][2]}</li> ` //设置背景颜色 li.style.backgroundColor = autocolor() //设置盒子高度 li.style.height = viewheight + 'px' //追加 viewlist[index].appendChild(li) } //更改下次页码 view_index[index][2]++ console.log(view_index) } //双击置顶 let nav_box = document.querySelector('.nav_box') nav_box.ondblclick = function () { viewlist[indextype].style.transition = 'all .5s' viewlist[indextype].style.top = '0px' view_index[indextype][0] = 0 } </script> </html>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持开心学习网。
您可能感兴趣
- js如何编辑数组对象里的数组(JS操作对象数组实现增删改查实例代码)
- jsforeach语句(JS面试题之forEach能否跳出循环详解)
- node.js怎么使用import(Node.js断点续传的实现)
- vue购物车怎么实现(Vue.js框架实现购物车功能)
- 数组reduce方法的好处(JS使用reduce方法处理树形结构数据)
- python pdf文件操作(Python常见读写文件操作实例总结文本、json、csv、pdf等)
- html和js代码结合(JS、CSS和HTML实现注册页面)
- php验证码图解(php/JS实现的生成随机密码验证码功能示例)
- JavaScriptSerializer对Json对象的序列化和反序列化
- js搜索功能的实现(前端JavaScript实现本地模糊搜索功能的方法实例)
- JS文件智能提示另一个JS文件中的成员
- qt和js相互调用(QT与javascript交互数据的实现)
- js轮播图片(JS实现简单图片轮播效果)
- js中数组的操作
- js回调函数
- 动态加载js脚本
- 以前全椒人是怎么过冬的 满满都是回忆(以前全椒人是怎么过冬的)
- NVIDIA显卡份额冲上88 A饭发愁 游戏优化恐没A卡份了(NVIDIA显卡份额冲上88A饭发愁)
- AMD YES A卡还是N卡 A卡和N卡的区别(AMDYESA卡还是N卡)
- 以后显卡多了一个新选择,N卡和A卡外又多了个I卡(以后显卡多了一个新选择)
- 读卖乐园的彩灯(读卖乐园的彩灯)
- 新疆80后在淘宝卖干果 以前是 不务正业 如今帮乡亲致富(新疆80后在淘宝卖干果)