如果鼠标移出菜单栏,然后再进去时,显示就会不正确了,是不是因为var leftCorner=mouseTrack[mouseTrack.length-2];计算会出错。
代码如下:
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <script> //二进制的正负表示是在最高位,1表示负,0表示正,抑或运算是仅当对应的2位有一位为1时才返回1,反过来如果抑或运算返回的结果是0(正),则一定是2个1,或者2个0.反之,则是一个0,一个1 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){//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){//用offset方法获取上下边缘 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) } </script> <script> $(function(){ var sub=$('#sub'); var activeRow;//选中的行 var activeMenu;//选中的行对应的二级菜单 var timer;//setTimeout返回的计时器id var mouseInSub=false;//当前鼠标是否在子菜单里 sub.on('mouseenter',function(e){ mouseInSub=true; }).on('mouseleave',function(e){ mouseInSub=false; }); //创建数组,记录 var mouseTrack=[];//数组跟踪记录鼠标的位置 var moveHandler=function(e){//鼠标离开菜单时,需要对绑定在document上的mousemove事件解绑,以免影响页面中其他组件,所以将事件监听函数独立出来,方便后续解绑操作 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);//mousemove事件一般绑定在document上 }) .on('mouseleave',function(e){ sub.addClass('none');//鼠标移动到一级菜单时,二级菜单隐藏 if(activeRow){//鼠标离开一级菜单,如果存在激活的行,样式要去掉,并把变量置空 activeRow.removeClass('active'); activeRow=null; } if(activeMenu){ activeMenu.addClass('none'); activeMenu=null; } $(document).unbind('mouseove',moveHandler); }) .on('mouseenter','li',function(e){//一级菜单的列表项绑定事件 sub.removeClass('none');//鼠标移动到一级菜单时,二级菜单显示 if(!activeRow){//移过去没有激活的一级菜单 activeRow=$(e.target); activeRow.addClass('active'); activeMenu=$('#'+activeRow.data('id')); activeMenu.removeClass('none'); return; } //debounce:mouseenter频繁触发时,只执行最后一次 if(timer){ clearTimeout(timer); } console.log(mouseTrack) 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=activeRow; var prevActiveMenu=activeMenu; activeRow=$(e.target); activeMenu=$('#'+activeRow.data('id')); prevActiveRow.removeClass('active'); prevActiveMenu.addClass('none');//上一次二级菜单隐藏 activeRow.addClass('active'); activeMenu.removeClass('none');//上一次二级菜单显示 } }); }); </script>
你好, 你90行的代码有问题,mousemove
不会报错么
非常感谢哦。。我正好非常懒得写。。复制粘贴了。我真的非常懒啊啊啊啊啊啊啊啊啊
border-right-width !=== border-raight-width
css 第十四行
html和css代码:
<style> .wrap{ position:relative; width:200px; left:50px; top:50px; } ul{ padding:15px 0; margin:9px; list-style:none; background:#6c6669; color:#fff; border-raight-width:0; } li{ display:block; height:30px; line-height:30px; padding-left:12px; cursor:pointer; font-size:14px; position:relative; } li.active{ background:#999395; } li span:hover{ color:#c81623; } .none{ display:none; } #sub{ width:600px; position:absolute; border:1px solid #f7f7f7; background:#f7f7f7; box-shadow:2px 0 5px rgba(0,0,0,.3); left:200px; top:0; box-sizing:border-box; margin:0; padding:10px; } .sub_content a{ font-size:12px; color:#666; text-decoration:none; } .sub_content dd a{ border-left:1px solid #e0e0e0; padding:0 10px; 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> </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="#">互联网品牌</a> </dd> </dl> <dl> <dt> <a href="#">电视<i>></i></a> </dt> <dd> <a href="#">合资品牌</a> <a href="#">国产品牌</a> <a href="#">互联网品牌</a> </dd> <dd> <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> </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> <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> </dd> <dd> <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="#">国产品牌</a> <a href="#">互联网品牌</a> </dd> <dd> <a href="#">合资品牌</a> <a href="#">国产品牌</a> <a href="#">互联网品牌</a> <a href="#">互联网品牌</a> <a href="#">互联网品牌</a> </dd> </dl> </div> </div> </div>