javascript - 检查 DOM 元素是否可以与之交互

标签 javascript jquery css dom

在我的 html5 应用程序中,我做了很多动态 dom 元素创建/操作。在某些情况下,我需要验证一个元素(例如 div)是否可以被用户“点击”。 “可点击”是指满足以下两个条件:

  • 它的计算 CSS 样式意味着它实际显示(即元素及其所有父元素的 displayvisibility 属性)
  • 它不会被任何其他元素遮挡,无论是具有更高的 z-index 还是稍后创建的绝对定位元素 - 在 DOM 的任何级别上,而不仅仅是其兄弟元素。

我可以使用纯 JS 或 jQuery。使用 jQuery 可以很容易地检查第一部分(即使用 .is(':visible')。但是,如果我有一个元素被另一个元素遮盖了,这仍然返回 true

如何检查元素是否真正可点击?

最佳答案

这使用标准视频游戏风格的碰撞测试来确定一个元素是否占据了另一个元素占据的全部空间。那部分我就不解释了,你可以看其他答案。

对我来说,解决这个问题的困难部分是尝试获取每个元素的 z-index 以确定一个元素实际上是在另一个元素之上还是之下。首先我们检查定义的 z-index,如果没有设置,我们检查父元素直到我们到达文档。如果我们在没有找到已定义的 z-index 的情况下一直到达文档,我们知道首先呈现的元素(标记在文档中较高)将在下方。

我已经将它实现为一个 jQuery 插件.. $("#myElement").isClickable()

$.fn.isClickable = function() {
  if (!this.length) return false;

  const getZIndex = e => {
    if (e === window || e === document) return 0;
    var z = document.defaultView.getComputedStyle(e).getPropertyValue('z-index');
    if (isNaN(z)) return getZIndex(e.parentNode);
    else return z;
  };

  var width = this.width(),
    height = this.height(),
    offset = this.offset(),
    zIndex = getZIndex(this[0]),
    clickable = true,
    target = this[0],
    targetIsBefore = false;

  $("body *").each(function() {
    if (this === target) targetIsBefore = true;
    if (!$(this).is(":visible") || this === target) return;

    var e_width = $(this).width(),
      e_height = $(this).height(),
      e_offset = $(this).offset(),
      e_zIndex = getZIndex(this),

      leftOfTarget = offset.left >= e_offset.left,
      rightOfTarget = width + offset.left <= e_width + e_offset.left,
      belowTarget = offset.top >= e_offset.top,
      aboveTarget = height + offset.top <= e_height + e_offset.top,
      behindTarget = e_zIndex === zIndex ? targetIsBefore : e_zIndex > zIndex;

    if (leftOfTarget && rightOfTarget && belowTarget && aboveTarget && behindTarget) clickable = false;
  });

  return clickable;
};

$(".clickme").click(function() {
  alert("u clicked " + this.id)
});

$(".clickme").each(function() {
  console.log("#"+this.id, $(this).isClickable() ? "is clickable" : "is NOT clickable");
})
#item1 {
  background: rgba(230, 30, 43, 0.3);
  position: absolute;
  top: 3px;
  left: 4px;
  width: 205px;
  height: 250px;
}

#item2 {
  background: rgba(30, 250, 43, 0.3);
  position: absolute;
  top: 100px;
  left: 50px;
  width: 148px;
  height: 50px;
}

#item3 {
  background: rgba(30, 25, 110, 0.3);
  position: absolute;
  top: 23px;
  left: 101px;
  width: 32px;
  height: 100px;
}

#item4 {
  background: rgba(159, 25, 110, 0.3);
  position: absolute;
  top: 10px;
  left: 45px;
  width: 23px;
  height: 45px;
  z-index: -111
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="item1" class='clickme'></div>
<div id="item2" class='clickme'></div>
<div id="item3" class='clickme'></div>
<div id="item4" class='clickme'></div>

关于javascript - 检查 DOM 元素是否可以与之交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48530923/

相关文章:

javascript - 表格行未在 Cordova/Phonegap 中水平显示

javascript - 单击时选择 Div 标记中的所有文本(即使用类)

javascript - 如果按下按键,Javascript

jquery - IE7 在悬停之前不会从导航中移除事件状态

javascript - 使用变量作为 JQuery 选择器

html - 如何更改进度条 Angular 指令的颜色

CSS 投影映射/四边形变形/Angular 销

javascript - 插入带有脚本的 jQuery 来更改元素

javascript - 如何在使用 jQuery 验证解散之前验证 Bootstrap 模态

javascript - jQuery HTML5 范围 slider 中的实时输出