課程代碼——20170503
如果鼠標移出菜單欄,然后再進去時,顯示就會不正確了,是不是因為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>
2017-05-03
你好, 你90行的代碼有問題,mousemove
2017-07-04
不會報錯么
2017-05-15
?非常感謝哦。。我正好非常懶得寫。。復制粘貼了。我真的非常懶啊啊啊啊啊啊啊啊啊
2017-05-12
border-right-width? !===?border-raight-width
css 第十四行
2017-05-03
html和css代碼: