javascript触发器悬停在绝对元素下的绝对元素和元素上

时间:2015-01-19 12:19:37

标签: javascript jquery html css angularjs

我想在两者上检测悬停事件:绝对定位元素和位于其下的元素。

以下简化问题:

HTML:

<div id="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
<div id="output"></div>    
<div id="output2"></div>
<svg width="40" height="40" id="svg">
    <circle r="20" cx="20" cy="20"></circle>
</svg>

CSS:

#content {
    background-color: green;    
}
#svg {
    position: absolute;
    left: 100px;
    top: 15px;
}

JS:

var output = $("#output");
$("#content").mouseenter(function(e){
    output.text("in text");
}).mouseout(function(e) {
    output.text("out text"); 
});

var output2 = $("#output2");
$("#svg").mouseenter(function(e){
    output2.text("in svg");
}).mouseleave(function(e) {
    output2.text("out svg"); 
});

并且jsfiddle:http://jsfiddle.net/r4xgq9s8/1/

编辑:

我希望得到以下结果:

  • (在文本中,在svg中)当你们两个都结束时,
  • (文字,在svg中)当你只是#svg,而不是#content,
  • 当你只是#content,而不是#svg,时,
  • (in text,out svg)
  • (out text,out svg)当你不在他们身上时

2 个答案:

答案 0 :(得分:2)

这不会起作用,因为圈子隐藏了它下面的内容。 但是您可以查看:

  • 制作内容的圆圈子。这样悬停事件就会起泡。这样,圆圈的所有内容都将输出&#34; over text&#34; svg&#34; svg&#34;这不是你想要的

  • 写一点数学并检查你是否在文本上

我会在这里尝试第二种方法:

&#13;
&#13;
var output = $("#output");
var inCircle = false;

$("#content").mouseenter(function(e) {
  output.text("in text");
}).mouseout(function(e) {
  output.text("out text");
});

var output2 = $("#output2");
$("#svg").mouseenter(function(e) {
  output2.text("in svg");
  inCircle = true;
}).mouseleave(function(e) {
  output2.text("out svg");
  inCircle = false;
});

$(document).mousemove(function(e) {

  if (!inCircle) return; // When not in circle we return here

  var $content = $('#content');
  var offset = $content.offset();

  // Check if in content-element
  if (e.pageX > offset.left &&
    e.pageX < offset.left + $content.width() &&
    e.pageY > offset.top &&
    e.pageY < offset.top + $content.height()) {

    $content.trigger('mouseenter');
  } else {
    $content.trigger('mouseout');
  }


});
&#13;
#content {
  background-color: green;
}
#svg {
  position: absolute;
  left: 100px;
  top: 15px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
<div id="output"></div>
<div id="output2"></div>
<svg width="40" height="40" id="svg">
  <circle r="20" cx="20" cy="20"></circle>
</svg>
&#13;
&#13;
&#13;

这里的诀窍是我们听文件 - 鼠标移动。每当我们进入圆圈并且鼠标移动到内容上时,我们就触发内容上的mouseenter。反之亦然,使用mouseleave。

答案 1 :(得分:0)

我添加了这个新答案来解决我的第一个答案的评论中提到的多边形点问题。

要检查point is in a polygon是否必须实施旨在解决此重要问题的算法。 我将在这里展示其中一个实现。

function point_in_polygon(P,R){

    function det(i){
        return (P[i].x - R.x) * (P[i+1].y - R.y) - (P[i+1].x - R.x) * (P[i].y - R.y);
    }

    var w = 0,
        len = p.length,
        i = 0,
        q = [];

    for(;i < len;++i){

        if(P[i].x > R.x && P[i].y >= R.y) q[i] = 0;
        if(P[i].x <= R.x && P[i].y > R.y) q[i] = 1;
        if(P[i].x < R.x && P[i].y <= R.y) q[i] = 2;
        if(P[i].x >= R.x && P[i].y < R.y) q[i] = 3;

    }

    q[len] = q[0];

    for(i = 0;i < len;++i){

        switch(q[i+1] - q[i]){
            case -3: ++w; break;
            case  3: --w; break;
            case -2: if(det(i) > 0) ++w; break;
            case  2: if(det(i) < 0) --w; break;
        }

    }

    return w;
}

此功能需要2个参数。第一个包含所有多边形的点,startPoint和endPoint相同:

var P = [
    {x:50, y:50},
    {x:200, y:30},
    {x:150, y:100},
    {x:300, y:300},
    {x:100, y:200},
    {x:50, y:50},
];

第二个是需要检查的当前点:

window.addEventListener('mousemove', function(e){

    var R = {x:e.pageX, y:e.pageY};

}

point_in_polygon - 函数返回winding-number,当该点在多边形内时,该值大于零。

当不使用盒子而是使用多边形时,此功能可以轻松适应所有情况。