當鼠標指向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)
2018-07-13
不用這樣,只要把邊距去掉在 li? 加點邊緣就行 就解決了
2017-08-08
因為你第32行是以主菜單(#test)綁定事件的 而主菜單有一個上邊緣和一個下邊緣 當你移到這個上邊緣或者下邊緣卻沒移到 li 元素上時 ?二級菜單sub顯示了 但是二級菜單里面的元素卻依然處于display:none狀態
你可以將32行改為('#test li')綁定到 li元素上 同時修改55行為.on('mouseenter',function(e)就可以了
不過我也遇到過問題 就是沒修改之前 我設置setTimeOut 能正常運行 但是我修改后 就失效了 不知道有沒有人知道是什么原因
2017-08-01
應該是 #sub的div樣式中的padding的問題。
2017-08-01
應該是id=sub的div吧,看看樣式