实现的效果动图如下
理清需求
拿到效果图的第一步,理清下需求~
首先,元素有左右上下四个方向。这边的问题在我如何在一个元素上划分上下左右四个区域?
然后,鼠标进入元素和离开元素会有触发一个事件,这个简单js就自带了监听事件。
最后,最难的是如何判断鼠标进入的时候会落在我们划分好的上下左右四个区域?
思路
-
首先我们先来划分下四个区域,一般划分的都如下图
图里面有四个三角形,每个三角形代表的是一个方向,所以问题简化为如何在一个矩形里,根据对角线划分区域。由于元素存在坐标系,也就是X、Y轴,所以问题再次抽象成,如何得到两条对角线的线性函数。(初高中数学问题。)
最后的问题我们就要来搞定判断鼠标落点的问题,首先我们知道我们可以在元素的鼠标事件中通过event得到鼠标的pageX和pageY,再配合元素的offsetLeft和offsetTop就可以得到鼠标在元素中的坐标。综合一下就变成了,我有一个坐标,且我知道对角线的函数表达式,请问我如何知道我这个坐标是在函数的下面还是上面?
当然也许描述的比较抽象,我们可以类比一个例子,我现在有一个坐标(2,1),有一个函数y=x,值域大于0(既y>0),定义域大于0(既x>0),求该坐标在y=x的函数下面还是上面?(是不是感觉到了线性规划得到最优解的味道,对,少年,没有错,就是这样。)这里我们只要把坐标中的x值代入函数,然后判断代入的结果是否大于坐标的y值,如果大于则在函数下面,小于则在函数上面,什么?你问等于怎么办?当然是在函数上面,该坐标即在上面又在下面,所谓薛定谔的坐标是也(当然是在函数上了)。
然后我们是不是可以扩展下,如果存在多个函数,再加上逻辑判断经常用的交集,并集是不是又有新的思维出现了呢?好了,这边就不再扩展了,下面直接上实现代码吧。
实现代码
注意:该demo只是简单的demo,其中有很多可以优化的地方,比如组件化,变量优化,利用发布订阅模式,实现事件联动
<!DOCTYPE html>
<html lang="ch">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css" >
.ct{
height: 100px;
width: 100px;
border:1px red solid;
}
</style>
</head>
<body>
<div class="ct" onmouseover="fun1(event);" onmouseout="fun2(event);">
</div>
<script type="text/javascript">
//当然这样绑定事件函数是不对的
var div=document.getElementsByTagName("div")[0];
function fun1(event){
var x=event.pageX-div.offsetLeft;//(得到鼠标在框中的坐标)
var y=event.pageY-div.offsetTop;//(得到鼠标在框中的坐标)
var H=div.clientHeight;
var W=div.clientWidth;
var k=Math.floor(H/W);//为了防止不能整除
//得到2个斜边函数
//设y=ax+c
//(0,0) (width,height)其中一个斜边过这两点
//a=height/width,c=0
//y=(height/width)*x;
//(0,height) (width,0)另外一个斜边过这两点
//a=-height/width,c=height
//y=-(height/width)*x+height
if((k*x)>=y && (H-k*x)>=y){//这是判断从上方进入,这边简化处理不对等于情况做特别处理
console.log("从上方进入");
//todo
}
if((k*x)<y && (H-k*x)<y){
console.log("从下方进入");
//todo
}
if((k*x)<y && (H-k*x)>y){
console.log("从左边进入");
//todo
}
if((k*x)>y && (H-k*x)<y){
console.log("从右边进入");
//todo
}
}
function fun2(event){
var x=event.pageX-div.offsetLeft;//(得到鼠标在框中的坐标)
var y=event.pageY-div.offsetTop;//(得到鼠标在框中的坐标)
var H=div.clientHeight;
var W=div.clientWidth;
var k=Math.floor(H/W);//为了防止不能整除
//得到2个斜边函数
//设y=ax+c
//(0,0) (width,height)其中一个斜边过这两点
//a=height/width,c=0
//y=(height/width)*x;
//(0,height) (width,0)另外一个斜边过这两点
//a=-height/width,c=height
//y=-(height/width)*x+height
if((k*x)>=y && (H-k*x)>=y){//这是判断从上方进入,这边简化处理不对等于情况做特别处理
console.log("从上方离开");
//todo
}
if((k*x)<y && (H-k*x)<y){
console.log("从下方离开");
//todo
}
if((k*x)<y && (H-k*x)>y){
console.log("从左边离开");
//todo
}
if((k*x)>y && (H-k*x)<y){
console.log("从右边离开");
//todo
}
}
</script>
</body>
</html>