zoukankan      html  css  js  c++  java
  • 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)
    }

  • 相关阅读:
    使用FolderBrowserDialog组件选择文件夹
    使用OpenFileDialog组件打开多个文
    使用OpenFileDialog组件打开对话框
    获取弹出对话框的相关返回值
    PAT 甲级 1139 First Contact (30 分)
    PAT 甲级 1139 First Contact (30 分)
    PAT 甲级 1138 Postorder Traversal (25 分)
    PAT 甲级 1138 Postorder Traversal (25 分)
    PAT 甲级 1137 Final Grading (25 分)
    PAT 甲级 1137 Final Grading (25 分)
  • 原文地址:https://www.cnblogs.com/yuer20180726/p/11100521.html
Copyright © 2011-2022 走看看