当鼠标指向div,但并没有指向li时,为什么会出现这种白框?
当鼠标指向div,但并没有指向li时,为什么会出现这种白框?
js代码:
/** Created by sofiaZ on 17/7/22.*/
$(document).ready(function(){ //ready事件,当DOM加载完毕且页面完全加载时发生。把所有jjQuery事件和函数置于该事件比较好。
var sub =$('#sub');//申明一个变量指向子菜单,这是直接转成
var activeRow; //申明一个变量,指向当前激活的以及菜单的行
var activeMenu; //二级菜单
//没赋初值时为false
var timer;
var mouseInsub = false; //标识当前鼠标是否在子菜单里
sub.on('mouseenter',function(e){
mouseInsub = true;
})
.on('mouseleave',function(e){
mouseInsub = false;
});
var mouseTrack = []; //创建一个数组,跟踪记录鼠标的位置
var moveHandler = function(e){
mouseTrack.push({ //push()方法向数组的末尾添加一个或多个元素,返回值为新数组的长度
x: e.pageX,
y: e.pageY //鼠标指针的位置,x相对于文档左边缘,y相对于文档上边缘
});
if (mouseTrack.length > 3) {
mouseTrack.shift(); //shift事件把数组的第一个元素删除,返回第一个元素的值。这里只想要当前以及上一次的坐标,因此保留三个就够了
}
};
$('#test')
.on('mouseenter',function(e) { //on事件,向元素添加事件处理程序
sub.removeClass('none'); //鼠标移动到元素时,出现二级菜单
$(document).bind('mousemove', moveHandler);
}
)
//document对象对应整个html文档,$(document)是对document的jquery操作,bind为元素添加事件(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('mousemove',moveHandler); //当鼠标离开菜单栏时,对mousemove事件进行解绑,以免影响页面其他事件
})
.on('mouseenter','li',function(e){
if (!activeRow){
activeRow = $(e.target);
activeRow.addClass('active');
activeMenu = $('#' + activeRow.data('id'));
activeMenu.removeClass('none');
return;
}
if (timer) {
clearTimeout(timer);
} //当事件还没触发时,清掉计时器,这样可以保证事件只触发最后一次的?(debounce去抖技术基本原理?)
var currMousePos = mouseTrack[mouseTrack.length - 1]; //当前鼠标坐标
var leftCorner = mouseTrack[mouseTrack.length - 2]; //上一次鼠标坐标
var delay = needDelay(sub, leftCorner, currMousePos);
if (delay) {
timer = setTimeout(function(){ //setTimeout返回值是一个ID?
if (mouseInsub) {
return;
}
activeRow.removeClass('active');
activeMenu.addClass('none');
activeRow = $(e.target);
activeRow.addClass('active');
activeMenu = $('#' + activeRow.data('id'));
activeMenu.removeClass('none'); //大概就是,移到下一个li时,跳过if,重新获取target与id??
timer = null; //这样的话,返回什么呢?? // 因为active是全局变量????
},300); //300毫秒后执行,这样当鼠标从一级菜单转换到二级菜单时,中间划过其他li也不会触动其对应的二级菜单,因为有延迟
}
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')
}
})
});函数的js代码:
/**
* Created by sofiaZ on 17/7/27.
*/
function sameSign(a, b) {
return(a ^ b) >=0; //a^b为a按位异或b,若结果为正(最高位为0),则a和b要么同正要么同负)
}
function vector(a,b){
return{
x: b.x- a.x,
y: b.y- a.x
}
}
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 + elem.height()
};
return isPointInTrangle(currMousePos, leftCorner, topLeft, bottomLeft)