image.pngHTML

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <link rel="stylesheet" href="./css/index.css">
  8. <title>Document</title>
  9. </head>
  10. <body>
  11. <div class="menu-wrap">
  12. <div class="main">
  13. <ul class="main-list">
  14. <li class="main-item active">
  15. <a href="javascript:;">菜单1</a>
  16. </li>
  17. <li class="main-item">
  18. <a href="javascript:;">菜单2</a>
  19. </li>
  20. <li class="main-item">
  21. <a href="javascript:;">菜单3</a>
  22. </li>
  23. <li class="main-item">
  24. <a href="javascript:;">菜单4</a>
  25. </li>
  26. <li class="main-item">
  27. <a href="javascript:;">菜单5</a>
  28. </li>
  29. <li class="main-item">
  30. <a href="javascript:;">菜单6</a>
  31. </li>
  32. <li class="main-item">
  33. <a href="javascript:;">菜单7</a>
  34. </li>
  35. <li class="main-item">
  36. <a href="javascript:;">菜单8</a>
  37. </li>
  38. <li class="main-item">
  39. <a href="javascript:;">菜单9</a>
  40. </li>
  41. <li class="main-item">
  42. <a href="javascript:;">菜单10</a>
  43. </li>
  44. </ul>
  45. </div>
  46. <div class="sub hide">
  47. <ul class="sub-list">
  48. <li class="sub-item active">子菜单1</li>
  49. <li class="sub-item">子菜单2</li>
  50. <li class="sub-item">子菜单3</li>
  51. <li class="sub-item">子菜单4</li>
  52. <li class="sub-item">子菜单5</li>
  53. <li class="sub-item">子菜单6</li>
  54. <li class="sub-item">子菜单7</li>
  55. <li class="sub-item">子菜单8</li>
  56. <li class="sub-item">子菜单9</li>
  57. <li class="sub-item">子菜单10</li>
  58. </ul>
  59. </div>
  60. </div>
  61. </body>
  62. <script src="./js/untils.js"></script>
  63. <script src="./js/index.js"></script>
  64. </html>

css

ul {
    padding: 0;
    margin: 0;
    list-style: none;
}

a {
    text-decoration: none;
}

.menu-wrap {
    position: relative;
    width: 200px;
    height: 440px;
    background-color: #424242;
    margin: 50px;
}

.menu-wrap .main {
    height: 100%;
}

.menu-wrap .main .main-item {
    height: 44px;
}

.menu-wrap .main .main-list .main-item a {
    display: block;
    height: 100%;
    text-align: center;
    line-height: 44px;
    color: #fff;
}
.menu-wrap .main .main-list .main-item.active a{
    background-color: #666;
    color: orange;
}
.menu-wrap .sub{
    position: absolute;
    top: 0px;
    left: 200px;
    width: 440px;
    height: 440px;
    background-color: #eeee;
}
.menu-wrap .sub.hide{
    display: none;
}
.menu-wrap .sub .sub-item{
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    line-height: 440px;
    text-align: center;
    font-size: 50px;
}

.menu-wrap .sub .sub-item.active{
    display: block;
}

js

window.onload = function () {
    init();
}

function init() {
    initMenu();
}

var initMenu = (function () {
    var oMenu = document.getElementsByClassName('menu-wrap')[0],
        oMenuItems = oMenu.getElementsByClassName('main-item'),
        menuLen = oMenuItems.length,
        oSub = document.getElementsByClassName('sub')[0],
        oSubItems = document.getElementsByClassName('sub-item'),
        subLen = oSubItems.length,
        isInSub = false,
        isFirst = true,
        menuItem,
        subItem,
        t = null,
        mousePoses = [];

    addEvent(oMenu, 'mouseenter', function () {
        addEvent(document, 'mousemove', mouseMove);
    });

    // 移除整个菜单
    addEvent(oMenu, 'mouseleave', menuMouseOut);

    for (var i = 0; i < menuLen; i++) {
        menuItem = oMenuItems[i];
        addEvent(menuItem, 'mouseenter', menuItemMouseEnter);
    }

    // 移动到子菜单时 就不要切换了
    addEvent(oSub, 'mouseenter', function () {
        isInSub = true;
    });

    addEvent(oSub, 'mouseleave', function () {
        isInSub = false;
    });

    function menuItemMouseEnter(e) {
        var e = e || window.event,
            tar = e.target || e.srcElement,
            thisIdx = Array.prototype.indexOf.call(oMenuItems, tar),
            posLen = mousePoses.length,
            //  求出 a、p 点
            curPos = mousePoses[posLen - 1] || {
                x: 0,
                y: 0
            },
            lastPos = mousePoses[posLen - 2] || {
                x: 0,
                y: 0
            };
        toDelay = doTimeout(lastPos, curPos);

        // console.log(toDelay);

        // console.log(curPos,lastPos);
        // Array.prototype.indexOf.call(列表集合,当前列表项)
        // 找当前项在列表里的下标
        oSub.className = 'sub';

        if (t) {
            clearTimeout(t);
        }
        if(!isFirst){
            if (toDelay) {
                t = setTimeout(function () {
                    if (isInSub) {
                        return;
                    }
                    addActive(thisIdx);
                    t = null;
                }, 300);
            } else {
                addActive(thisIdx);
            }
        }else{
            addActive(thisIdx);
            isFirst = false;
        }

    }

    function addActive(index) {
        removeAllActive();
        // 将选中的内容增加class名
        oMenuItems[index].className += ' active';
        oSubItems[index].className += ' active';
    }

    // 去除所有样式
    function removeAllActive() {
        for (var i = 0; i < menuLen; i++) {
            menuItem = oMenuItems[i];
            subItem = oSubItems[i];
            menuItem.className = 'main-item';
            subItem.className = 'sub-item';
        }
    }

    function menuMouseOut() {
        oSub.className += ' hide';
        removeAllActive();
        removeEvent(document, 'mousemove', mouseMove);
    }

    function mouseMove(e) {
        var e = e || window.event;
        count = 0;
        mousePoses.push({
            x: pagePos(e).X,
            y: pagePos(e).Y
        })
        if (mousePoses.length >= 3) {
            mousePoses.shift();
        }
    }

    // 求出 B、C 点
    function doTimeout(lastPos, curPos) {
        var TL = {
            x: getStyles(oMenu, 'margin-left') + getStyles(oMenu, 'width'),
            y: getStyles(oMenu, 'margin-top')
        }

        var BL = {
            x: getStyles(oMenu, 'margin-left') + getStyles(oMenu, 'width'),
            y: getStyles(oMenu, 'margin-top') + getStyles(oMenu, 'height')
        }
        // console.log(TL, BL)
        return pointInTriangle({
            curPos: curPos,
            lastPos: lastPos,
            topLeft: TL,
            bottomLeft: BL
        })
    }
});

setTimeout:执行一次自动停止
setInterval 循环执行 直至clearInterval