您的位置:首页 > Web前端

【前端笔记】慕课网—无延迟二级菜单加载及demo

2018-01-02 22:51 441 查看
前记
演示效果

重点

所需框架

实现笔记
html
左半边的一级菜单布局使用ul和li标签代码片段

右边二级菜单的html结构

CSS样式

JS 代码

前记

演示效果



重点

1、页面布局及CSS知识

2、如何实现无延迟加载

所需框架

Jquery

实现笔记

html

左半边的一级菜单,布局使用ul和li标签,代码片段:

<ul>
<li data-id="a">
<span>家用电器</span>
</li>
…………
<li data-id="j">
<span> 手机 / 运用商 / 数码 </span>
</li>
</ul>


说明:

(1)ul是无序列表,li标签定义列表的内容,自带·的样式,它们都是块级元素

(2)data-*是自定义数据,用于存储页面或应用程序的私有自定义数据,赋予我们在所有 HTML 元素上嵌入自定义 data 属性的能力

右边二级菜单的html结构

首先使用div作为父级容器,然后在用若干个div表示每一个一级菜单所对应的二级菜单。

在每一个二级菜单div中,使用了dl、dt、dd元素作为布局的标签,实例代码部分如下:

<div id="sub" class="none">
<div id="a" class="sub_content none">
<dl>
<dt>
<a href="#">电视1<i>></i></a>
</dt>

<dd>
<a href="#">合资品牌</a>
<a href="#">国产品牌</a>
<a href="#">互联网品牌</a>
</dd>
</dl>

......


说明:

(1)dl 标签定义了定义列表(definition list)

(2)dl 标签用于结合 dt (定义列表中的项目)和 dd (描述列表中的项目)。

CSS样式

这部分需要记录的是一级菜单鼠标移上去时的高亮效果

li.active{
background: #999395;
}
li span:hover{
color: #c81623;
}


更多具体的样式可以参考源码

JS 代码

具体的代码详解参考代码中的注释:

$(document).ready(function () {
var sub = $('#sub')  //二级菜单的父div

var activeRow
var activeMenu

//优化
var timer
var mouseInSub = false

var mouseTrack=[]

var moveHandler=function(e){
mouseTrack.push({
x:e.pageX,
y:e.pageY
})

if(mouseTrack.length>3){
mouseTrack.shift()
}
}

sub.on('mouseenter', function (e) {
//当鼠标放在二级菜单上是,标志位设为true
mouseInSub = true
}).on('mouseleave', function (e) {
//同上离开时设置为false
mouseInSub = false
})

//id test为整个一二级菜单的父容器div
$('#test').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)
console.log('mouse leave bind handler')

})

$('#test') //鼠标进入菜单时,注册鼠标移动时的回调事件
.on('mouseenter',function(e){
$(document).bind('mousemove',moveHandler)
console.log('mouse enter bind handler')
})

$('#test li').on('mouseenter',function (e) {
sub.removeClass('none')
if (!activeRow) {
activeRow = $(e.target).addClass('active')
activeMenu = $('#' + activeRow.data('id'))
activeMenu.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)

if(delay){
console.log("delay")
timer = setTimeout(function () {

if (mouseInSub) {
console.log("----")
return
}

activeRow.removeClass('active')
activeMenu.addClass('none')

activeRow = $(e.target)
activeRow.addClass('active')
activeMenu = $('#' + activeRow.data('id'))
activeMenu.removeClass('none')
timer = null
}, 500)
}else{
console.log(" no delay")

var prevActiveRow=activeRow
var prevActiveMenu=activeMenu

activeRow=$(e.target)
activeMenu=$('#'+activeRow.data('id'))

prevActiveMenu.addClass('none')
prevActiveRow.removeClass('active')

activeRow.addClass('active')
activeMenu.removeClass('none')
}
})
})


说明:

(1)三角形的图如下所示:



(2)有关向量判断的方法都封装在了函数function.js当中,源码如下:

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 sameSign(a,b){
return (a^b)>=0
}
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,curMousePos){
var offset =elem.offset()
var topLeft={
x:offset.left,
y:offset.top
}
var bottomLeft={
x:offset.left+elem.width(),
y:offset.top+elem.height()

}

return isPointInTrangle(curMousePos,leftCorner,topLeft,bottomLeft)
}


本实例是慕课网上的一个课程,有兴趣的小伙伴可以去看看~

慕课网视频教程:JS实现京东无延迟菜单效果

结束:附上源码 码云:JS实现京东无延迟菜单效果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jquery html 前端