广告位招租虚拟主机

实例:Js实现京东无延迟菜单效果(demo)

2017-06-05??来源:cnblogs.com??我有话说??收藏本文

这是一个js实现京东无延迟菜单效果,感觉很好,分享给大家。先来看实例展示:

70570130.gif

(点击放大)

先来理清思路:

1.开发基本的菜单结构;

2.开发普通的二级菜单效果;

3.假如延迟解决移动问题?

切换子菜单时候,用setTimeout设置延迟

debounce去抖技

在事件被频繁触发时,只执行一次处理

4.解决延迟引入的新问题

跟踪鼠标的移动

用鼠标当前位置,和鼠标上一次位置与子菜单上下边缘的三角形区域进行比较

运用到向量

二位向量叉乘公式

用叉乘法判断点在三角形内

最终效果:鼠标自然的移动和点击到子菜单,切换时无延迟。

代码如下:

开发基本的菜单结构


    
    京东菜单无刷新
    
    
    

    

解决第2、3个问题

$(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()
        }
    }

    $('#test')
        .on('mouseenter',function(e){
            sub.removeClass('none')

            $(document).bind('mousemove',moveHandler)
        })
        .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(!activeRow){
                activeRow = $(e.target).addClass('acrive')
                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){                // 时间触发,设置一个缓冲期
                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')
            }
        })
})

解决延迟引入的新问题

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){    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.top + elem.height()
    }    return isPointInTrangle(currMousePos,leftCorner,topLeft,bottomLeft)
}


当你看到这,也就实现了京东的无延迟菜单效果,同时也为你点赞,能看到这儿。

(责编:边缘)
阅读??次??|??打印??|??关闭
匿名评论

用微信扫一扫

新网巢