从当前鼠标位置绘制三角形。

3

我目前拥有一个分类下拉菜单,当用户悬停在主分类上时,会加载子分类。

<div class="all-categories">
  <li><a href="#">Category 1</a></li>
  <li><a href="#">Category 2</a></li>
  <li><a href="#">Category 3</a></li>
  // More categories here
</div>

我想要创建一个安全区域,以避免下拉菜单的不必要更改,类似于亚马逊的做法。
我目前正在使用以下函数来跟踪鼠标悬停在“.all-categories”上时的位置:
function handleMouseMove(event) {
    var eventDoc, doc, body;

    event = event || window.event; // IE-ism

    // If pageX/Y aren't available and clientX/Y are,
    // calculate pageX/Y - logic taken from jQuery.
    // (This is to support old IE)
    if (event.pageX == null && event.clientX != null) {
            eventDoc = (event.target && event.target.ownerDocument) || document;
        doc = eventDoc.documentElement;
        body = eventDoc.body;

        event.pageX = event.clientX +
              (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
              (doc && doc.clientLeft || body && body.clientLeft || 0);
        event.pageY = event.clientY +
              (doc && doc.scrollTop  || body && body.scrollTop  || 0) -
              (doc && doc.clientTop  || body && body.clientTop  || 0 );
    }

    // Use event.pageX / event.pageY here
    console.log(event.pageX + ", " + event.pageY);
}

jQuery(document).ready(function () {
  document.querySelector(".all-categories").onmousemove = handleMouseMove;

});

现在,我该如何从我的光标位置创建一个三角形,使其连接到 .all-categories div 的右上角和右下角?
非常感谢您的帮助。 :)

我不明白你想在这里画三角形的目的,如果你想防止用户尝试进入子菜单时出现意外的菜单更改,那么我认为你应该采取另一种方法。例如,尝试在显示子菜单时设置一个时间延迟约200或300毫秒。如果光标在此时间之前移开,则简单地取消它。 - Yavuz Tas
@YavuzTas 谢谢你的评论,我尝试过了,但用户体验会受到影响,因为他需要等待一段时间才能看到子菜单,这也导致导航不够流畅。 - Brian Moreno
如果你对自己编写此内容没有强烈的热情,那么我找到了一个看起来不错且类似于你想要的实现,以供参考:amazonsidebarmanu - Yavuz Tas
1个回答

0
你需要创建一个带有 position: absolute 属性的三角形元素,就像这样:

#triangle {
    border-color: yellow blue red green;
    border-style: solid;
    border-width: 100px 100px 100px 100px ;
    width:0;
    height:0;
}
<div id="triangle"></div>

然后将鼠标事件附加到 document 而不是 .all-categories

jQuery(document).ready(function() {
  var Triangle, boxCoords, boxWidth, boxHeight;
  boxCoords = $(".all-categories")[0].getBoundingClientRect();
  //console.log(rect.top, rect.right, rect.bottom, rect.left);
  boxWidth = parseInt(boxCoords.right - boxCoords.left);
  boxHeight = parseInt(boxCoords.bottom - boxCoords.top);
  Triangle = $('#triangle');
  Triangle.css('top', boxCoords.top + 'px');
  
  $(document).on("mousemove", function(event) {
    // if outside the box return
    if (event.pageX < boxCoords.left || event.pageX > boxCoords.right ||
      event.pageY < boxCoords.left || event.pageY > boxCoords.bottom) {
      //Triangle.hide();
      return;
    }

    //Triangle.show();
    var triangleBorder = (event.pageY - boxCoords.top) + 'px ';
    triangleBorder += (boxWidth - (event.pageX - boxCoords.left)) + 'px ';
    triangleBorder += (boxCoords.bottom - event.pageY) + 'px ';
    triangleBorder += (event.pageX - boxCoords.left) + 'px';
    Triangle.css('border-width', triangleBorder);
  });
});
html,body {margin: 20px}
.all-categories {
  border: 1px solid #ddd;
  display: inline-block;
  padding-right: 20px;
  box-sizing: border-box;
}
li {margin: 10px 5px}
#triangle {
  position: absolute;
  border-color: transparent rgba(3, 169, 244, 0.58) transparent transparent;
  border-style: solid;
  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="all-categories">
  <li><a href="#">Category 1</a></li>
  <li><a href="#">Category 2</a></li>
  <li><a href="#">Category 3</a></li>
  <li><a href="#">Category 4</a></li>
  <li><a href="#">Category 5</a></li>
  <li><a href="#">Category 6</a></li>
  <li><a href="#">Category 7</a></li>

</div>
<div id="triangle"></div>


这没问题,但如果它被用作安全点,那么在mousemove上更新它听起来有点奇怪。它应该基于活动菜单切换元素生成,否则,它不会防止任何不良事件的发生。 - Kaiido

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接