课程代码——20170503

来源:4-2 基于用户行为预测的切换技术

aSuncat

2017-05-03 18:57

如果鼠标移出菜单栏,然后再进去时,显示就会不正确了,是不是因为var leftCorner=mouseTrack[mouseTrack.length-2];计算会出错。

代码如下:

<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
  //二进制的正负表示是在最高位,1表示负,0表示正,抑或运算是仅当对应的2位有一位为1时才返回1,反过来如果抑或运算返回的结果是0(正),则一定是2个1,或者2个0.反之,则是一个0,一个1
  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){//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){//用offset方法获取上下边缘
    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)
  }
</script>
<script>
  $(function(){
    var sub=$('#sub');
    var activeRow;//选中的行
    var activeMenu;//选中的行对应的二级菜单
    var timer;//setTimeout返回的计时器id
    var mouseInSub=false;//当前鼠标是否在子菜单里
    sub.on('mouseenter',function(e){
      mouseInSub=true;
    }).on('mouseleave',function(e){
      mouseInSub=false;
    });

    //创建数组,记录
    var mouseTrack=[];//数组跟踪记录鼠标的位置
    var moveHandler=function(e){//鼠标离开菜单时,需要对绑定在document上的mousemove事件解绑,以免影响页面中其他组件,所以将事件监听函数独立出来,方便后续解绑操作
      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);//mousemove事件一般绑定在document上
      })
      .on('mouseleave',function(e){
        sub.addClass('none');//鼠标移动到一级菜单时,二级菜单隐藏

        if(activeRow){//鼠标离开一级菜单,如果存在激活的行,样式要去掉,并把变量置空
          activeRow.removeClass('active');
          activeRow=null;
        }
        if(activeMenu){
          activeMenu.addClass('none');
          activeMenu=null;
        }

        $(document).unbind('mouseove',moveHandler);
      })
      .on('mouseenter','li',function(e){//一级菜单的列表项绑定事件
        sub.removeClass('none');//鼠标移动到一级菜单时,二级菜单显示
        if(!activeRow){//移过去没有激活的一级菜单
          activeRow=$(e.target);
          activeRow.addClass('active');

          activeMenu=$('#'+activeRow.data('id'));
          activeMenu.removeClass('none');
          return;
        }
        //debounce:mouseenter频繁触发时,只执行最后一次
        if(timer){
          clearTimeout(timer);
        }
        console.log(mouseTrack)
        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');//上一次二级菜单显示
        }
      });

  });
</script>


写回答 关注

5回答

  • 呵呵SN
    2017-05-03 22:05:11
    已采纳

    你好, 你90行的代码有问题,mousemove

    aSunca...

    谢谢。

    2017-05-22 15:34:23

    共 2 条回复 >

  • qq_若谷_1
    2017-07-04 13:35:14

    不会报错么

  • 青春无敌美少女
    2017-05-15 17:14:08

     非常感谢哦。。我正好非常懒得写。。复制粘贴了。我真的非常懒啊啊啊啊啊啊啊啊啊

  • 十指狂魔
    2017-05-12 14:28:54

    border-right-width  !=== border-raight-width

    css 第十四行

  • aSuncat
    2017-05-03 18:58:23

    html和css代码:

      <style>
        .wrap{
          position:relative;
          width:200px;
          left:50px;
          top:50px;
        }
        ul{
          padding:15px 0;
          margin:9px;
          list-style:none;
          background:#6c6669;
          color:#fff;
          border-raight-width:0;
        }
        li{
          display:block;
          height:30px;
          line-height:30px;
          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;
          position:absolute;
          border:1px solid #f7f7f7;
          background:#f7f7f7;
          box-shadow:2px 0 5px rgba(0,0,0,.3);
          left:200px;
          top:0;
          box-sizing:border-box;
          margin:0;
          padding:10px;
        }
        .sub_content a{
          font-size:12px;
          color:#666;
          text-decoration:none;
        }
        .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;
          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>
      </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="#">互联网品牌</a>
            </dd>
          </dl>
          <dl>
            <dt>
              <a href="#">电视<i>&gt;</i></a>
            </dt>
            <dd>
              <a href="#">合资品牌</a>
              <a href="#">国产品牌</a>
              <a href="#">互联网品牌</a>
            </dd>
            <dd>
              <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>
            </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>
            <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>
            </dd>
            <dd>
              <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="#">国产品牌</a>
              <a href="#">互联网品牌</a>
            </dd>
            <dd>
              <a href="#">合资品牌</a>
              <a href="#">国产品牌</a>
              <a href="#">互联网品牌</a>
              <a href="#">互联网品牌</a>
              <a href="#">互联网品牌</a>
            </dd>
          </dl>
        </div>
      </div>
    
    </div>


JS实现京东无延迟菜单效果

JS模拟京东商城无延迟菜单效果,学习菜单结构和样式处理

57661 学习 · 138 问题

查看课程

相似问题