如何使用jQuery检测两个div是否相触?

36

我正在开发一个简单的气球游戏,使用了两个

元素。问题在于当这两个
元素相互接触时,我无法触发一个函数。


那么div在移动吗?或者到底发生了什么,你想要引起什么? - justkt
你正在使用jQuery的可拖动功能或其他类似的工具吗?为了得到回答,这个问题需要更多的信息和澄清。 - Tejs
请提供更多信息和一些代码。 - Ant
1
这真的值得一个踩吗?即使加上示例代码会更好,但它是一个相关、清晰的问题。而且还是一个新用户。 - Matt
这个问题可能也与以下问题相关:https://dev59.com/217Va4cB1Zd3GeqPLaDa - Anderson Green
4个回答

60
你正在寻找边界框碰撞检测的方法。如果你想要触发一个事件,你必须反复测试,但最好的方法是从你的游戏循环中对所有游戏对象运行该函数。沙盒在http://jsfiddle.net/nGRwt/7/
  function collision($div1, $div2) {
      var x1 = $div1.offset().left;
      var y1 = $div1.offset().top;
      var h1 = $div1.outerHeight(true);
      var w1 = $div1.outerWidth(true);
      var b1 = y1 + h1;
      var r1 = x1 + w1;
      var x2 = $div2.offset().left;
      var y2 = $div2.offset().top;
      var h2 = $div2.outerHeight(true);
      var w2 = $div2.outerWidth(true);
      var b2 = y2 + h2;
      var r2 = x2 + w2;

      if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) return false;
      return true;
    }

2
如何编辑此代码以使div并排显示但不重叠? - Rutger Kappers
嘿@BC,你介意我复制并自由使用这段代码而不进行归属吗? - D.Tate
我通常不会在评论中说谢谢,但是这真的很有用,非常感谢啊伙计。 - Kyle
这是一个很棒的解决方案!非常感谢 @BC。 - D. Ahmed

11
你可以尝试使用jquery-collision加上jquery-ui-draggable-collision。完整披露:我刚刚在SourceForge上编写并发布了这些内容。

第一个允许这样做:

var hit_list = $("#collider").collision(".obstacle");

这是所有与“#collider”重叠的“.obstacle”列表。

第二个允许:

$("#collider").draggable( { obstacle: ".obstacle" } );

其中之一是提供了“collision”事件可以绑定:

$("#collider").bind( "collision", function(event,ui){...} );

而且你甚至可以设置:

$("#collider").draggable( { obstacle: ".obstacle", preventCollision: true } );

在拖动时,防止“#collider”与任何“.obstacle”重叠。


你有jquery-collision.min.js的CDN链接或URL吗? - Kurkula

3

在原生的Javascript中

var is_colliding = function(div1, div2) {
  var d1_height = div1.offsetHeight;
  var d1_width = div1.offsetWidth;
  var d1_distance_from_top = div1.offsetTop + d1_height;
  var d1_distance_from_left = div1.offsetLeft + d1_width;

  var d2_height = div2.offsetHeight;
  var d2_width = div2.offsetWidth;
  var d2_distance_from_top = div2.offsetTop + d2_height;
  var d2_distance_from_left = div2.offsetLeft + d2_width;

  var not_colliding =
    d1_distance_from_top < div2.offsetTop ||
    div1.offsetTop > d2_distance_from_top ||
    d1_distance_from_left < div2.offsetTop ||
    div1.offsetLeft > d2_distance_from_left;

  return !not_colliding;
};

2

Victor S的回答很有用,但我需要检查两个div是否完全重叠,即被遮挡(但这很难在谷歌上搜索,因为结果中充斥着对Eclipse IDE的引用)。

分享我修改后的版本,以防有人觉得有用:

$(function() {
  /**
   * Function to determine whether the first element completely 
   *  eclipses the second element
   */
  function collision($div2, $div1) {
    var x1 = $div1.offset().left;
    var y1 = $div1.offset().top;
    var h1 = $div1.outerHeight(true);
    var w1 = $div1.outerWidth(true);
    var b1 = y1 + h1;
    var r1 = x1 + w1;
    var x2 = $div2.offset().left;
    var y2 = $div2.offset().top;
    var h2 = $div2.outerHeight(true);
    var w2 = $div2.outerWidth(true);
    var b2 = y2 + h2;
    var r2 = x2 + w2;

    return x1 > x2 && y1 > y2 && b1 < b2 && r1 < r2
      ? true
      : false
  }

  // draggable jQuery listener required jQuery UI
  // Just used to illustrate the above
  $('#div1,#div2').draggable({
    drag: function() {
      if (collision($('#div1'), $('#div2'))) {
        $('#div2').text('Eclipsing').css({'background-color': 'grey'})
      } else {
        $('#div2').text('Not eclipsing').css({'background-color': 'green'})
      }

      $('#result').text(collision($('#div1'), $('#div2')));

    }
  });
});
.box {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}

#div1 {
  width: 200px;
  height: 200px;
  background-color: pink;
}
#div2 {
  width: 75px;
  height: 75px;
  background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script>

<strong>Drag divs around.</strong>
<p>Eclipsing? <span id="result">false</span>

<div id="wrapper">
  <div id="div1" class="box">
    Div1
  </div><br/>
  <div id="div2" class="box">
    Not eclipsing
  </div>
</div>


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