Js实现京东无延迟菜单效果(demo)
程序员文章站
2022-03-18 10:41:49
...
一个端午节,外面人山人海,又那么热,我认为宅在家里看看慕课网,充实自己来的实际...
这是一个js实现京东无延迟菜单效果,感觉很好,分享给大家...
先来理清思路:
1.开发基本的菜单结构
2.开发普通的二级菜单效果
3.假如延迟解决移动问题
切换子菜单时候,用setTimeout设置延迟
debounce去抖技
在事件被频繁触发是,只执行一次处理
4.解决延迟引入的新问题
跟踪鼠标的移动
用鼠标当前位置,和鼠标上一次位置与子菜单上下边缘的三角形区域进行比较
运用到向量
二位向量叉乘公式
用叉乘法判断点在三角形内
最终效果:鼠标自然的移动和点击到子菜单 切换时无延迟
下面开始代码:
开发基本的菜单结构
<!doctype html><html lang="en"><head><meta charset="UTF-8"><title>京东菜单无刷新</title><script src="js/jquery-1.7.2.min.js?1.1.11"></script><script src="js/mche.js?1.1.11"></script><script src="js/function.js?1.1.11"></script><style>.wrap{position:relative;width:200px;left:50px;top:50px;}ul{padding:15px;margin:9;list-style:none;background:#6c6669;color:#ffffff;border-right-width:0;}/*水平居中*/li{display:block;height:30px;line-height: 30px;padding-left:12px;cursor:pointer;font-size: 14px;position:relative;}/*鼠标移动上去的背景色*/li.active{background:#999395;}/*js可以很好地调用类,一般效果css实现就好*/li span:hover{color:#c81623;}/*隐藏的类*/.none{display: none;}/*二级菜单*/#sub{width:600px;position: absolute;border:1px solid #f7f7f7;background:#f7f7f7;box-shadow:2px 0 rgba(0,0,0,.3);left: 200px;top:0;box-sizing:border-box;margin: 0px;padding:10px;}.sub-content a{font-style:12px;color:#666;text-decoration:none;}.sub-content dd a{border-left:1px solid #e0e0e0;padding:0 1px;margin:4px 0;}.sub-content dl {overflow:hidden;}.sub-content dt{float: left;width:70px;font-weight: bold;clear:left;position:relative;}.sub-content dd {float: left;margin-left: 5px;border-top:1px solid #eee;margin-bottom: 5px;}.sub-content dt i{width:4px;height: 14px;font:400 9px/14px consolas;position: absolute;right:5px;top:5px;}</style></head><body><div class="wrap" id="test"><ul><li data-id="a"><span>家用电器</span> </li><li data-id="b"><span>手机 / 运营商 / 数码</span> </li><li data-id="c"><span>电脑办公 / 办公</span> </li><li data-id="d"><span>家居 / 家具 / 家装 / 厨具</span> </li><li data-id="e"><span>男装 / 女装 / 童装 / 内衣 </span> </li><li data-id="f"><span>美妆个护 / 宠物 </span> </li><li data-id="g"><span>女鞋 / 箱包 / 钟表 / 珠宝 </span> </li><li data-id="h"><span>男鞋 / 运动 / 户外</span> </li><li data-id="i"><span>汽车 / 汽车用品 </span> </li></ul><div id="sub" class="none"><div id="a" class="sub-content none"><dl><dt><a href="#">电视<i>></i></a></dt><dd><a href="#">曲面电视</a><a href="#">超薄电视</a><a href="#">HDR电视</a><a href="#">DLED电视</a></dd><dt><a href="#">空调<i>></i></a></dt><dd><a href="#">挂壁式空调</a><a href="#">柜式空调</a><a href="#">*空调</a><a href="#">以旧换新</a></dd><dt><a href="#">洗衣机<i>></i></a></dt><dd><a href="#">滚筒式洗衣机</a><a href="#">洗烘一体机</a><a href="#">波轮洗衣机</a><a href="#">迷你洗衣机</a></dd></dl></div><div id="b" class="sub-content none"><dl><dt><a href="#">手机通讯<i>></i></a></dt><dd><a href="#">手机</a><a href="#">对讲机</a><a href="#">以旧换新</a><a href="#">手机维修</a></dd><dt><a href="#">运营商<i>></i></a></dt><dd><a href="#">合约机</a><a href="#">选号机</a><a href="#">固定电话</a><a href="#">办宽带</a></dd><dt><a href="#">手机配件<i>></i></a></dt><dd><a href="#">手机壳</a><a href="#">贴膜</a><a href="#">手机存储卡</a><a href="#">数据线</a></dd></dl></div><div id="c" class="sub-content none"><dl><dt><a href="#">电脑整机<i>></i></a></dt><dd><a href="#">笔记本</a><a href="#">游戏本</a><a href="#">平板电脑</a></dd><dt><a href="#">电脑配件<i>></i></a></dt><dd><a href="#">显示器</a><a href="#">CPU</a><a href="#">主板</a></dd><dt><a href="#">外设产品<i>></i></a></dt><dd><a href="#">鼠标</a><a href="#">键盘</a><a href="#">键盘套餐</a></dd></dl></div><div id="d" class="sub-content none"><dl><dt><a href="#">厨具<i>></i></a></dt><dd><a href="#">烹饪锅具</a><a href="#">刀剪配件</a><a href="#">厨房配件</a><a href="#">水具酒具</a></dd><dt><a href="#">家纺<i>></i></a></dt><dd><a href="#">床品套件</a><a href="#">被子</a><a href="#">枕芯</a><a href="#">蚊帐</a></dd><dt><a href="#">生活日用<i>></i></a></dt><dd><a href="#">收纳用品</a><a href="#">雨伞雨具</a><a href="#">净化除味</a><a href="#">浴室用品</a></dd></dl></div><div id="e" class="sub-content none"><dl><dt><a href="#">女装<i>></i></a></dt><dd><a href="#">商城同款</a><a href="#">当季热卖</a><a href="#">2017新品</a><a href="#">连衣裙</a></dd><dt><a href="#">男装<i>></i></a></dt><dd><a href="#">商城同款</a><a href="#">当季热卖</a><a href="#">2017新品</a><a href="#">牛仔裤</a></dd></dl></div><div id="f" class="sub-content none"><dl><dt><a href="#">面部护肤<i>></i></a></dt><dd><a href="#">补水保湿</a><a href="#">卸妆</a><a href="#">洁面</a></dd></dl></div></div></ul></body></html>
解决第2、3个问题
$(document).ready(function(){var sub = $('#sub')var activeRowvar activeMenuvar timervar mouseInSub = falsesub.on('mouseenter',function(e){ mouseInSub = true}).on('mouseleave',function(e){ mouseInSub = false})var mouseTrack = []var moveHandler = function(e){ mouseTrack.push({ x:e.pageX, y:e.pageY })if(mouseTrack.length > 3){ mouseTrack.shift() } } $('#test') .on('mouseenter',function(e){ sub.removeClass('none') $(document).bind('mousemove',moveHandler) }) .on('mouseleave',function(e){ sub.addClass('none')if(activeRow){ activeRow.removeClass('active') activeRow = null; }if(activeMenu){ activeMenu.addClass('none') activeMenu = null; }//解绑$(document).unbind('mousemove',moveHandler) }) .on('mouseenter','li',function(e){if(!activeRow){ activeRow = $(e.target).addClass('acrive') activeMenu = $('#'+activeRow.data('id')) activeMenu.removeClass('none')return}//清除if(timer){ clearTimeout(timer) }//鼠标当前坐标var currMousePos = mouseTrack[mouseTrack.length - 1]//上次的坐标var leftCorner = mouseTrack[mouseTrack.length-2]var delay = needDelay(sub,leftCorner,currMousePos)if(delay){// 时间触发,设置一个缓冲期timer = setTimeout(function(){//判断if(mouseInSub){return} activeRow.removeClass('active') activeMenu.addClass('none') activeRow = $(e.target) activeRow.addClass('active') activeMenu = $('#'+ activeRow.data('id')) activeMenu.removeClass('none') timer = null}, 300) }else{var prevActiveRow = activeRowvar prevActiveMenu = activeMenu activeRow = $(e.target) activeMenu = $('#' + activeRow.data('id')) prevActiveRow.removeClass('active') prevActiveMenu.addClass('none') activeRow.addClass('active') activeMenu.removeClass('none') } }) })
解决延迟引入的新问题
function sameSign(a,b){return (a ^ b) >= 0}function vector(a,b){return{ x:b.x - a.x, y:b.y - a.y } }function vectorProduct(v1,v2){return v1.x * v2.y - v2.x * v1.y }function isPointInTrangle(p,a,b,c){var pa = vector(p,a)var pb = vector(p,b)var pc = vector(p,c)var t1 = vectorProduct(pa,pb)var t2 = vectorProduct(pb,pc)var t3 = vectorProduct(pc,pa)return sameSign(t1,t2) && sameSign(t2,t3) } function needDelay(elem,leftCorner,currMousePos){var offset = elem.offset()var topLeft = { x:offset.left, y:offset.top }var bottomLeft = { x:offset.left, y:offset.top + elem.height() }return isPointInTrangle(currMousePos,leftCorner,topLeft,bottomLeft) }
当你看到这,也就实现了京东的无延迟菜单效果,同时也为你点赞,能看到这儿。
一入IT行业深似海,给我的感觉,,保持一个积极学习的心态是必须的,用博客记录我前进的脚步。
有什么问题,可以留言,大家一起讨论,一起进步。
以上就是Js实现京东无延迟菜单效果(demo)的详细内容,更多请关注其它相关文章!
下一篇: 解决vue 路由变化页面数据不刷新的问题