Home >Web Front-end >JS Tutorial >Js realizes Jingdong's delay-free menu effect (demo)

Js realizes Jingdong's delay-free menu effect (demo)

巴扎黑
巴扎黑Original
2017-06-26 15:04:511207browse

It’s the Dragon Boat Festival, there are so many people outside, and it’s so hot. I think I can stay at home and read MOOCs to enrich my experience. ...

This is a js to achieve JD.com’s delay-free menu effect. It feels very good and I would like to share it with everyone...

<span style="color: #000000">先来理清思路:<br>1.开发基本的菜单结构     

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

3.假如延迟解决移动问题 
  切换子菜单时候,用setTimeout设置延迟

  debounce去抖技
  在事件被频繁触发是,只执行一次处理

4.解决延迟引入的新问题  
  跟踪鼠标的移动
  用鼠标当前位置,和鼠标上一次位置与子菜单上下边缘的三角形区域进行比较
  
  运用到向量
  二位向量叉乘公式
  用叉乘法判断点在三角形内</span>

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

Start the code below:

Develop basic Menu structure

<!doctype html><html lang="en"><head><meta charset="UTF-8"><title>京东菜单无刷新</title><script src="js/jquery-1.7.2.min.js?1.1.11"></script><script src="js/mche.js?1.1.11"></script><script src="js/function.js?1.1.11"></script><style>.wrap{position:relative;width:200px;left:50px;top:50px;}ul{padding:15px;margin:9;list-style:none;background:#6c6669;color:#ffffff;border-right-width:0;}/*水平居中*/li{display:block;height:30px;line-height: 30px;padding-left:12px;cursor:pointer;font-size: 14px;position:relative;}/*鼠标移动上去的背景色*/li.active{background:#999395;}/*js可以很好地调用类,一般效果css实现就好*/li span:hover{color:#c81623;}/*隐藏的类*/.none{display: none;}/*二级菜单*/#sub{width:600px;position: absolute;border:1px solid #f7f7f7;background:#f7f7f7;box-shadow:2px 0 rgba(0,0,0,.3);left: 200px;top:0;box-sizing:border-box;margin: 0px;padding:10px;}.sub-content a{font-style:12px;color:#666;text-decoration:none;}.sub-content dd a{border-left:1px solid #e0e0e0;padding:0 1px;margin:4px 0;}.sub-content dl {overflow:hidden;}.sub-content dt{float: left;width:70px;font-weight: bold;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;}</style></head><body><div class="wrap" id="test"><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><li data-id="h"><span>男鞋 / 运动 / 户外</span>    </li><li data-id="i"><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><a href="#">HDR电视</a><a href="#">DLED电视</a></dd><dt><a href="#">空调<i>&gt</i></a></dt><dd><a href="#">挂壁式空调</a><a href="#">柜式空调</a><a href="#">中央空调</a><a href="#">以旧换新</a></dd><dt><a href="#">洗衣机<i>&gt</i></a></dt><dd><a href="#">滚筒式洗衣机</a><a href="#">洗烘一体机</a><a href="#">波轮洗衣机</a><a href="#">迷你洗衣机</a></dd></dl></div><div id="b" class="sub-content none"><dl><dt><a href="#">手机通讯<i>&gt</i></a></dt><dd><a href="#">手机</a><a href="#">对讲机</a><a href="#">以旧换新</a><a href="#">手机维修</a></dd><dt><a href="#">运营商<i>&gt</i></a></dt><dd><a href="#">合约机</a><a href="#">选号机</a><a href="#">固定电话</a><a href="#">办宽带</a></dd><dt><a href="#">手机配件<i>&gt</i></a></dt><dd><a href="#">手机壳</a><a href="#">贴膜</a><a href="#">手机存储卡</a><a href="#">数据线</a></dd></dl></div><div id="c" class="sub-content none"><dl><dt><a href="#">电脑整机<i>&gt</i></a></dt><dd><a href="#">笔记本</a><a href="#">游戏本</a><a href="#">平板电脑</a></dd><dt><a href="#">电脑配件<i>&gt</i></a></dt><dd><a href="#">显示器</a><a href="#">CPU</a><a href="#">主板</a></dd><dt><a href="#">外设产品<i>&gt</i></a></dt><dd><a href="#">鼠标</a><a href="#">键盘</a><a href="#">键盘套餐</a></dd></dl></div><div id="d" class="sub-content none"><dl><dt><a href="#">厨具<i>&gt</i></a></dt><dd><a href="#">烹饪锅具</a><a href="#">刀剪配件</a><a href="#">厨房配件</a><a href="#">水具酒具</a></dd><dt><a href="#">家纺<i>&gt</i></a></dt><dd><a href="#">床品套件</a><a href="#">被子</a><a href="#">枕芯</a><a href="#">蚊帐</a></dd><dt><a href="#">生活日用<i>&gt</i></a></dt><dd><a href="#">收纳用品</a><a href="#">雨伞雨具</a><a href="#">净化除味</a><a href="#">浴室用品</a></dd></dl></div><div id="e" class="sub-content none"><dl><dt><a href="#">女装<i>&gt</i></a></dt><dd><a href="#">商城同款</a><a href="#">当季热卖</a><a href="#">2017新品</a><a href="#">连衣裙</a></dd><dt><a href="#">男装<i>&gt</i></a></dt><dd><a href="#">商城同款</a><a href="#">当季热卖</a><a href="#">2017新品</a><a href="#">牛仔裤</a></dd></dl></div><div id="f" class="sub-content none"><dl><dt><a href="#">面部护肤<i>&gt</i></a></dt><dd><a href="#">补水保湿</a><a href="#">卸妆</a><a href="#">洁面</a></dd></dl></div></div></ul></body></html>

Solution to the 2nd and 3rd problems

$(document).ready(function(){var sub = $('#sub')var activeRowvar activeMenuvar timervar mouseInSub = falsesub.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 = activeRowvar prevActiveMenu = activeMenu

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

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

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

Solution to new problems introduced by delay

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

When you see this, it will be realized Jingdong’s no-delay menu effect, and also likes you, you can see it here.

#Once in The IT industry is as deep as the sea, which gives me the feeling that it is necessary to maintain a positive learning attitude. I use a blog to record my progress.

## If you have any questions, you can leave a message and we can discuss and make progress together.

The above is the detailed content of Js realizes Jingdong's delay-free menu effect (demo). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn