商品导航栏菜单

html部分

<div class="wrap" id="text">
<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>
<li data-id="f"><span>玩具</span></li>
<li data-id="g"><span>男装/女装/孩子装</span></li>
</ul>
<div id="sub" class="none">
<div id="a" class="sub_content none">
<dl>
<dt><a href="#">电视<i>&gt;</i></a></dt>
<dd><a href="#">文字文字</a><a href="#">文字文字</a></dd>
</dl>
</div>
<div id="b" class="sub_content none">
<dl>
<dt><a href="#">电视1<i>&gt;</i></a></dt>
<dd><a href="#">文字文字</a><a href="#">文字文字</a></dd>
</dl>
</div>
<div id="c" class="sub_content none">
<dl>
<dt><a href="#">电视2<i>&gt;</i></a></dt>
<dd><a href="#">文字文字</a></dd>
</dl>
</div>
<div id="d" class="sub_content none">
<dl>
<dt><a href="#">电视3<i>&gt;</i></a></dt>
<dd><a href="#">文字文字</a><a href="#">文字文字</a></dd>
</dl>
</div>
<div id="e" class="sub_content none">
<dl>
<dt><a href="#">电视4<i>&gt;</i></a></dt>
<dd><a href="#">文字文字</a></dd>
</dl>
</div>
<div id="f" class="sub_content none">
<dl>
<dt><a href="#">电视5<i>&gt;</i></a></dt>
<dd><a href="#">文字文字</a><a href="#">文字文字</a></dd>
</dl>
</div>
<div id="g" class="sub_content none">
<dl>
<dt><a href="#">电视6<i>&gt;</i></a></dt>
<dd><a href="#">文字文字</a></dd>
</dl>
</div>
</div>
</div>

css部分

.wrap{
position: relative;
width:200px ;
top:0px;
left: 50px;
}
.wrap ul{
margin: 9px;
background:#6c6669 ;
color:#fff ;
border-right-width:0 ;
}
.wrap li{
display:block;
height:30px;
line-height:30px ;
padding-left:12px ;
cursor:pointer ;
font-size:14px ;
position: relative;
}
.wrap li.active{
background:#999395 ;
}
.wrap li a{
color:#fff ;
}
.wrap li a: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,0.3) ;
left: 190px;
top: 0;
box-sizing: border-box;
margin: 0;
padding: 10px;
height:240px ;
}
.sub_content a{
font-size:12px ;
color: #666;
}
.sub_content dd a{
border-left:1px solid #e0e0e0 ;
padding: 0 10px;
margin:4px 0 ;
}
.sub_content dl{
overflow: hidden;
margin:8px 0 ;
}
.sub_content dt{
float: left;
width: 70px;
font-weight:600 ;
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;

}

js部分

$(document).ready(function(){

var sub = $('#sub') //声明变量 指向子菜单

var activeRow; //激活的一级菜单的行 用于后续样式修改
var activeMenu; //对应的二级菜单
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({
x: e.pageX,
y: e.pageY
})

/*只保留三个位置信息
* 如果鼠标位置数组大于三 则弹出多余的位置信息
* */
if(mouseTrack.length>3){
mouseTrack.shift();
}

}

/* 为一级菜单绑定事件 */
$('#text')
.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('mousemove',moveHandler); //解绑

})
/*
* 为一级菜单中的每一个列表项绑定事件
* 使用动态代理的方式为列表绑定事件
* 优点: 便于增加和删除 性能好
*
* */
.on('mouseenter','li',function(e){

if(e.target.tagName.toLowerCase() =='li') {
//console.log(e.target.tagName.toLowerCase() )
if(!activeRow){
activeRow = $(e.target).addClass('active');
activeMenu = $('#' + activeRow.data('id'));
activeMenu.removeClass('none');
return
}
//console.log($(e.target));
//console.log(e.currentTarget);
//debounse 祛抖
if(timer){
clearTimeout(timer); //清除计时器
}


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');

}


}else{
return;
}


})

})

/***************/

/* 判断向量的符号 */

function sameSign(a, b){
return (a ^ b) >= 0
}


/* 向量的定义就是终点坐标减去起点坐标 */
function vector(a,b){
return {
x: b.x - a.x,
y: b.y - a.y
}
}

/* 向量的叉乘公式
向量1的x坐标 * 向量2的y坐标 - 向量2的x坐标 * 向量1的y坐标
* */
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, currMosuePos){
var offset = elem.offset();


var topLeft = {
x: offset.left,
y: offset.top

}

var bottomLeft = {
x: offset.left,
y: offset.top + elem.height()

}

return isPointInTrangle(currMosuePos, leftCorner, topLeft, bottomLeft);
}

posted @ 2017-05-22 09:34  阳光透过幸福  阅读(121)  评论(0编辑  收藏  举报