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

前记

演示效果

重点

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>&gt;</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)三角形的图如下所示:


1.png

(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实现京东无延迟菜单效果

微信公众号

若有疑问可以QQ联系笔者,虽然不一定100%解决你的问题,但是可以交流探讨一波:2276604211

顺便打个内推广告:如果有想入职中国银联上海技术开发的童鞋,也可以加上面的QQ资讯,笔者可以帮你回答一些相关问题~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353