这是一个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)的详细内容。
