实现鼠标进入进出div时位置的监听效果

来源:互联网 发布:ubuntu安装vc 编辑:程序博客网 时间:2024/04/27 02:21
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>判断鼠标进入容易的方向,js判断划入方向</title><script src="http://code.jquery.com/jquery-1.11.1.min.js"></script><script>$(function() {$("#box").on("mouseenter mouseleave",function(e) {var w = $(this).width();var h = $(this).height();var x=(e.pageX-this.offsetLeft-(w/2))*(w>h?(h/w):1);var y=(e.pageY-this.offsetTop-(h/2))*(h>w?(w/h):1);var dirNum=Math.round((((Math.atan2(y,x)*(180/Math.PI))+180)/90)+3)%4;/*dirNum:0,1,2,3 ---> t r b l以上代码是网友分享以下代码是模仿拉勾网首页的一个小效果做的*/var eventType = e.type;var aPos=[{left:0,top:-200},{left:200,top:0},{left:0,top:200},{left:-200,top:0}];if(eventType == 'mouseenter'){$("#box2").css(aPos[dirNum]).stop(true,true).animate({left:0,top:0},200);}else{$("#box2").stop(true,true).animate(aPos[dirNum],200);}});});</script><style>#box{width: 200px;height: 200px;border:1px solid #999;margin: 200px auto;position:relative;zoom:1;overflow: hidden;}#box1{height: 200px;background-color: orange;text-align: center;line-height: 200px;}#box2{position: absolute;left: -200px;top: -200px;width: 200px;height: 200px;background-color: red;text-align: center;line-height: 200px;}</style></head><body><div id="box"><div id="box1">#box1</div><div id="box2">#box2</div></div></body></html>

//////////

/////////

实现原理

编者按:还记得亚马逊左侧分类导航的光速hover事件吗?它被一些闲的蛋疼的前端从业者无数次拿来津津乐道。刚好逛博客园的时候,又看到这样一篇文章,反正博客每天都需要更新,所以特此转来充个数,以下代码演示涉及到jQuery,建议前端大牛绕路。

  $("#wrap").bind("mouseenter mouseleave",function(e) {           var w = $(this).width();           var h = $(this).height();           var x = (e.pageX - this.offsetLeft - (w / 2)) * (w > h ? (h / w) : 1);           var y = (e.pageY - this.offsetTop - (h / 2)) * (h > w ? (w / h) : 1);           var direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4; //direction的值为“0,1,2,3”分别对应着“上,右,下,左”           var eventType = e.type;           var dirName = new Array('上方','右侧','下方','左侧');           if(e.type == 'mouseenter'){              $("#result").html(dirName[direction]+'进入');          }else{              $('#result').html(dirName[direction]+'离开');          }      });
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
代码laycode - v1.1
 

就这么几行代码,将我印象里会有一长串的if else或者switch来完成的事完美的解决掉。在感到神奇之后,更多的是不解,因为看不懂。在网上搜索一番,也没有找到有谁来分析这个算法。于是自己研究了一下,现在写下来,作为自己的一份学习笔记,也希望能够和大家分享。

有不对的地方,或者有更好的理解,请告诉我,谢谢!

原理:以div容器的中心点作为圆心,以高和宽的最小值作为直径画圆,将圆以[π/4,3π/4),[3π/4,5π/4),[5π/4,7π/4),[-π/4,π/4)划分为四个象限,鼠标进入容器时的点的atan2(y,x)值在这四个象限里分别对应容器边框的下,右,上,左。如下图所示

js判断鼠标进入容器的方向小解

var x = (e.pageX - this.offsetLeft - (w / 2)) * (w > h ? (h / w) : 1);
  1. 1
代码laycode - v1.1

计算x坐标值时,如果点原来的x坐标的绝对值大于圆的半径值,则按 h/w 这个比例进行缩小,使得到的点的位置在容器的边界位置所对应的象限区间里。 y 坐标的计算也是一样。

var direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
  1. 1
代码laycode - v1.1
((Math.atan2(y, x) * (180 / Math.PI)将点的坐标对应的弧度值换算成角度度数值,这里加上180并非必要,只是为了使得到的0,1,2,3能够与习惯性的上,右,下,左的位置对照,如果不加上180,得到的0,1,2,3就会分别对应下,右,上,左。*修正:这里加上180不是并非必要的,而是在这个算法里必须的,因为atan2(y,x)返回值的范围是[-π,π],而不是我们习惯的[0,2π],负值会影响结果的正确性(比如右上和右下算出来的结果会不同),而且确实也使得得到的结果0,1,2,3的顺序符合了习惯(原作者可能没想这个,只是css里总是这个顺序,或许是我自己的习惯~)。除以90,再取四舍五入值,是一个很精妙的用法,使得可以以45°为分界线。分析完这个算法后,我内心有些激动。这里并没有用到什么高深的知识,即使是三角函数的基础知识都可以不知道(虽然初中就学了),但是可以用这么短短的三两行代码,就把我脑袋里浮现的那一长串的if else抛向云和山的彼端去,真的让我很难抑制内心的激动,深深的体会到算法之美,数学之美。

    0 0