qq_老老实人_0
2018-05-29 15:53
$(document).ready(function () { var sub = $('#sub'); var row; //每个<li> var menu; //二级菜单 var timer; var mouseInsub = false; //鼠标是否进入到二级菜单的一个flag var mouseTrack = []; var moveHandler = function (e) { mouseTrack.push({ //插入鼠于当前页面的坐标 x: e.pageX, y: e.pageY }); if(mouseTrack.length > 3){ //数组中只需要保存当前位置和上一次的位置 mouseTrack.shift(); } }; //检查鼠标是否移入到二级菜单,如果移到了二级菜单,则下面定时器直接返回 sub.on("mouseenter",function () { mouseInsub = true; }).on("mouseleave",function () { mouseInsub = false; }); $("#test") .on("mouseenter",function (e) { //mouseover移入子元素会触发mouseout,这个不会 sub.removeClass("none"); //常识,mousemove绑定在document上,鼠标在div上移动触发该事件,移出时记得清除 $(document).bind("mousemove",moveHandler); }) .on("mouseleave",function (e) { sub.addClass("none"); if(row){ row.removeClass("active"); row = null; } if(menu){ menu.addClass("none"); menu = null; } $(document).unbind("mousemove",moveHandler); }) .on("mouseenter","li",function (e) { //只在$("#test")下的“li”才触发 if(!row){ row = $(e.target).addClass("active"); //e.target当前指向的真正元素 menu = $("#" + row.data("id")); menu.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); console.log(currMousePos, leftCorner,delay); if(delay){ //如果在三角形内,这需要延迟 timer = setTimeout(function () { //防止鼠标打斜进入二级菜单 if(mouseInsub){ //鼠标在二级菜单里的话 return; } row.removeClass("active"); //得写在下面,写在上面row未定义报错 menu.addClass("none"); row = $(e.target).addClass("active"); menu = $("#" + row.data("id")); //data-xx属性都可以这样,如data-id menu.removeClass("none"); } ,300); }else{ row.removeClass("active"); //移除上一任样式 menu.addClass("none"); row = $(e.target).addClass("active"); //给当前所指li添加样式 menu = $("#" + row.data("id")); menu.removeClass("none"); } }) }); function isSameSign(a,b) { return (a ^ b) >= 0; //a异或b大于等于则认为符合相同 //最高位的异或运算,不相同返回1 } function vector(a,b) { //向量 var a = a || {}; var b = b || {}; return{ //终点坐标 - 起点坐标 x: b.x - a.x, y: b.y - a.y }; } function vectorProduct(v1,v2) { //向量X乘公式 return v1.x * v2.y - v1.y * v2.x; //向量1的x坐标 * 向量2的y坐标 - 向量1的y坐标 * 向量2的x坐标 } 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); //返回向量X乘结果 var t2 = vectorProduct(pb, pc); var t3 = vectorProduct(pc, pa); return isSameSign(t1,t2) && isSameSign(t2,t3); } function needDelay(elem,leftCorner,currMousePos) { if (!currMousePos || !leftCorner) { return; } var offset = elem.offset(); //jquery的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); }
跟老师的代码一样的吧
JS实现京东无延迟菜单效果
57664 学习 · 138 问题
相似问题