• Js实现京东无延迟菜单效果(demo) 慕课网


    先来理清思路:1.开发基本的菜单结构     
    
    2.开发普通的二级菜单效果
    
    3.假如延迟解决移动问题 
      切换子菜单时候,用setTimeout设置延迟
    
      debounce去抖技
      在事件被频繁触发是,只执行一次处理
    
    4.解决延迟引入的新问题  
      跟踪鼠标的移动
      用鼠标当前位置,和鼠标上一次位置与子菜单上下边缘的三角形区域进行比较
      
      运用到向量
      二位向量叉乘公式
      用叉乘法判断点在三角形内
    最终效果:鼠标自然的移动和点击到子菜单
             切换时无延迟

    下面开始代码:

    开发基本的菜单结构

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>京东菜单无刷新</title>
        <script src="js/jquery-1.7.2.min.js"></script>
        <script src="js/mche.js"></script>
        <script src="js/function.js"></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>

    解决第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)
    }

  • 相关阅读:
    MySQL修改root密码的多种方法
    AES和RSA算法的demo代码
    网卡
    Socket
    Opentracing 链路追踪
    TCP连接三次握手
    MongoDB 使用B树
    MySQL的DDL、DML、DCL
    MySQL 数据同步
    SSO(单点登录)与CAS
  • 原文地址:https://www.cnblogs.com/yuer20180726/p/11100521.html
Copyright © 2020-2023  润新知