css 如何在交互被禁用的情况下获取悬停元素?

xdyibdwo  于 2023-03-24  发布在  其他
关注(0)|答案(1)|浏览(117)

我正在做一个类似于浏览器inspect功能的扩展,当你在inpect模式下,用户应该不能与页面元素交互,但是光标悬停的元素应该被高亮显示。
我可以显示一个叠加图(当启用检查模式时),这会阻止用户与页面元素进行交互。但这里的问题是我无法获得悬停元素的尺寸,因为覆盖层位于所有其他元素的顶部。在覆盖层上将pointer-events设置为none可以工作,因为我可以获得覆盖层下页面上的单个元素,但是现在的问题是用户可以与页面元素交互。
我尝试通过简单地遍历所有DOM节点并设置pointer-events: none来禁用页面元素的交互,但是当我这样做时,我没有得到我悬停在上面的元素(而是得到body)。
所以我的问题是,如何在禁用交互的情况下获得悬停的元素?

n6lpvg4x

n6lpvg4x1#

您可以在body上附加一个事件处理程序,以在捕获阶段拦截和取消所有鼠标/键盘等事件,然后在主体中添加一个mousemove处理程序来进行检查。body上的事件处理程序将与特定的event.target一起调度。
请注意,悬停伪元素仍然处于激活状态。我不知道有什么简单的方法来防止这种情况- Firefox devtools也会在Inspect Element会话期间显示悬停效果,但Chrome不会。
有趣的旁注:在元素上指定pointer-events: none * 确实 * 禁用了初始悬停效果,尽管滚动会激活它。为body *添加这样的规则会创建 Flink 效果,所以我怀疑这不是一个很好的领域。

var detailsDiv = document.getElementById("details");
var overlayDiv = document.getElementById("overlay");

function cancelEvents(e) {
  e.preventDefault();
  e.stopImmediatePropagation();
}

document.body.addEventListener("click", cancelEvents, true);
document.body.addEventListener("mousedown", cancelEvents, true);
document.body.addEventListener("mouseup", cancelEvents, true);

document.body.addEventListener("mousemove", function(e) {
  var target = e.target;
  var bounds = target.getBoundingClientRect();
  if (target.id) {
    detailsDiv.innerHTML = summary(target, bounds);
    showOverlay(bounds);
  } else {
    detailsDiv.innerHTML = "";
    hideOverlay();
  }
});

function summary(target, bounds) {
  return "Over: " + target.id + " [" + bounds.width + "x" + bounds.height + "]";
}

function showOverlay(bounds) {
  overlayDiv.style.display = "block";
  overlayDiv.style.left = (bounds.left + window.scrollX) + "px";
  overlayDiv.style.top = (bounds.top + window.scrollY) + "px";
  overlayDiv.style.width = bounds.width + "px";
  overlayDiv.style.height = bounds.height + "px";
}

function hideOverlay() {
  overlayDiv.style.display = "none";
}
#red {
  width: 100px;
  height: 100px;
  background: red;
}

#blue {
  width: 50px;
  height: 50px;
  background: blue;
}

#yellow {
  width: 80px;
  height: 120px;
  background: yellow;
}

/* Possibly fly in the ointment */
#yellow:hover {
  background: orange;
}

#green {
  width: 120px;
  height: 80px;
  background: green;
}

#details {
  position: fixed;
  left: 200px;
  pointer-events: none;
}

#overlay {
  position: absolute;
  pointer-events: none;
  z-index: 999;
  box-sizing: border-box;
  border: 2px solid cyan;
  display: none;
}
<div id="details"></div>
<div id="overlay"></div>

<div id="red" onClick="alert('Clicked red')">
  <div id="blue"></div>
</div>
<div id="yellow"></div>
<div id="green"></div>

相关问题