一个好用的H5tab切换(抽屉功能)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <style>
        .wrap {
  position: relative;
  width: 200px;
  left: 50px;
  top: 50px;
  background: #6c6669;
  padding: 15px 0;
}
ul {
  list-style: none;
  margin: 0;
  padding: 0;
  color: #fff;
  border-right-width: 0;
}
li {
  height: 40px;
  line-height: 40px;
  padding-left: 12px;
  cursor: pointer;
  font-size: 14px;
  position: relative;
}
li.active {
  background: #999395;
}
li span:hover {
  color: #c81623;
}
.none {
  display: none;
}
#sub {
  width: 600px;
  min-height: 270px;
  position: absolute;
  border: 1px solid #f7f7f7;
  background: #f7f7f7;
  box-shadow: 2px 0 5px rgba(0, 0, 0, 0.3);
  left: 200px;
  top: 0;
  box-sizing: border-box;
  margin: 0;
  padding: 10px;
}
.sub_content a {
  text-decoration: none;
  color: #666;
  font-size: 12px;
}
.sub_content dd a {
  border-left: 1px solid #e0e0e0;
  padding: 0 10px;
  margin: 4px 0;
}
.sub_content dl {
  overflow: hidden;
}
.sub_content dt {
  float: left;
  width: 70px;
  clear: left;
  font-weight: bold;
  position: relative;
}
.sub_content dd {
  float: left;
  margin-left: 5px;
  border-top: 1px solid #eee;
  margin-bottom: 5px;
}

    </style>
</head>
<body>
    <div class="wrap" id="wrap">
        <ul>
          <li data-id="a">
            <span> 一级导航1 </span>
          </li>
          <li data-id="b">
            <span> 一级导航2 </span>
          </li>
          <li data-id="c">
            <span> 一级导航3 </span>
          </li>
          <li data-id="d">
            <span> 一级导航4 </span>
          </li>
          <li data-id="e">
            <span> 一级导航5 </span>
          </li>
          <li data-id="f">
            <span> 一级导航6 </span>
          </li>
        </ul>
        <div id="sub" class="none">
          <div id="a" class="sub_content none">
            <dl>
              <dt>
                              <a href="#"> 二级菜单1 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单1 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单1 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <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="#"> 二级菜单2 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单2 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单2 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单2 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单2 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单2 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <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="#"> 二级菜单3 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单3 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单3 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
          </div>
          <div id="d" class="sub_content none">
            <dl>
              <dt>
                              <a href="#"> 二级菜单4 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单4 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单4 </a> 
                              </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单4 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <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="#"> 二级菜单5 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单5 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
          </div>
          <div id="f" class="sub_content none">
            <dl>
              <dt>
                              <a href="#"> 二级菜单6 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单6 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单6 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单6 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
            <dl>
              <dt>
                              <a href="#"> 二级菜单6 </a>
                          </dt>
              <dd>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
                <a href="#"> 三级菜单 </a>
              </dd>
            </dl>
          </div>
        </div>
      </div>
</body>
<script>
    
$(document).ready(function() {
    var sub = $("#sub");
    var activeRow, //  已激活的一级菜单
        activeMenu; //  已激活的子级菜单

    var timer;

    // 鼠标是否在子菜单里
    var mouseInSub = false;
    sub.on("mouseenter", function() {
        mouseInSub = true;
    })
    .on("mouseleave", function() {
        mouseInSub = false;
    });

    // 记录鼠标的位置
    var mouseTrack = [];
    var moveHandler = function(e) {
        mouseTrack.push({
            x: e.pageX,
            y: e.pageY
        });

        // 只需要当前点和上一个点
        if (mouseTrack.length > 3) {
            mouseTrack.shift();
        }
    };

    // 此处只能给整个菜单注册,而非只给一级菜单加,否则timer中的回调执行时,activeRow已为空
    $("#wrap").on("mouseenter",    function() {
        sub.removeClass("none");
        $(document).bind("mousemove", moveHandler);// 用于记录鼠标位置
    })
    .on("mouseleave", function() {
        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) {
            active(e.target);
            return;
        }
        if (timer) {
            clearTimeout(timer);
        }

        var curMouse = mouseTrack[mouseTrack.length - 1]; // 鼠标当前坐标
        var prevMouse = mouseTrack[mouseTrack.length - 2]; // 鼠标上一次坐标
        // console.log(curMouse, prevMouse);
        var delay = needDelay(sub, curMouse, prevMouse);

        if (delay) {
            // 加入延迟器,解决斜方移动切换,只能折线移动的问题
            timer = setTimeout(function() {
                    if (mouseInSub) {
                        return;
                    }
                    activeRow.removeClass("active");
                    activeMenu.addClass("none");
                    active(e.target);

                    timer = null;
                }, 300);
        } else {
            activeRow.removeClass("active");
            activeMenu.addClass("none");
            active(e.target);
        }
    });

    function active(target) {
        activeRow = $(target);
        activeRow.addClass("active");
        activeMenu = $("#" + activeRow.data("id"));
        activeMenu.removeClass("none");
    }
});


// 向量是终点坐标减去起点坐标
function vector(a, b) {
  return {
    x: b.x - a.x,
    y: b.y - a.y
  };
}

// 向量的叉乘
function vectorPro(v1, v2) {
  return v1.x * v2.y - v1.y * v2.x;
}

// 用位运算高效判断符号相同
function sameSign(a, b) {
  return (a ^ b) >= 0;
}

// 判断点是否在三角形内
function isPointInTranjgle(p, a, b, c) {
  var pa = vector(p, a);
  var pb = vector(p, b);
  var pc = vector(p, c);

  var t1 = vectorPro(pa, pb);
  var t2 = vectorPro(pb, pc);
  var t3 = vectorPro(pc, pa);

  return sameSign(t1, t2) && sameSign(t2, t3);
}

// 是否需要延迟
function needDelay(ele, curMouse, prevMouse) {
  if (!curMouse || !prevMouse) {
    return;
  }
  var offset = ele.offset();

  // 左上点
  var topleft = {
    x: offset.left,
    y: offset.top
  };
  // 左下点
  var leftbottom = {
    x: offset.left,
    y: offset.top + ele.height()
  };

  return isPointInTranjgle(curMouse, prevMouse, topleft, leftbottom);
}

</script>
</html>
原文地址:https://www.cnblogs.com/ilylmy/p/13684735.html