有没有办法创建一个元素,当不同的元素悬停在并跟随光标时出现? 编辑:编辑编辑 2

问题描述

目标

正如标题所说,我想有两个元素,元素 A 和元素 B。我想让元素 B 只在元素 A 悬停时显示,但我也希望元素 B 跟随光标 无抖动。

我可以让悬停/显示部分独立工作,我可以让以下光标部分独立工作,但我似乎无法在不使用 offsetX/offsetY 的情况下将它们放在一起,这会导致它抖动。

代码

编辑:

由于某种原因,代码片段无法正常工作,只需将代码复制到文件中即可。

HTML:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <div id="content">
      <div id="A"></div>
      <div id="B"></div>
    </div>
  </body>
  <script src="script.js"></script>
</html>

CSS:

* {
 margin: 10px;
}

#content {
  position: absolute; /* Not needed in this example,but required for what I'm trying to make,I'm adding it because it might be relevant. */
  border: 5px solid green;
}

#A {
  border: 5px solid red;
  width: 500px;
  height: 500px;
}

#B {
  display: none;
  position: absolute;
  border: 5px solid blue;
  width: 100px;
  height: 100px;
}

#A:hover~#B {
  display: block;
}

和 JavaScript:

let b = document.getElementById('B');

const onMouseMove = (e) =>{
  b.style.left = e.offsetX + 'px';
  b.style.top = e.offsetY + 'px';
}

document.addEventListener('mousemove',onMouseMove);

说明

如您所见,A 和 B 都在 content div 中。如果我将其中一个移出,则悬停操作将停止工作。但是,如果您尝试运行它,您会看到 B 闪烁一堆(您可能需要从 CSS 中删除 display: none),并且“传送”到左上角。据我所知(来自 Google),这是因为我使用的是 offsetX/offsetY 而不是 pageX 和 pageY。我可以把它改成那个,但是因为它是相对于页面的,而且我试图相对于父元素(在这种情况下为 content)设置它,它不在正确的位置并且在你缩放时发生变化,这是个大问题。不过,这里真正的问题是 A 和 B 需要具有相同的父元素 (content) 才能使悬停/显示 CSS 工作,而 B 需要在 body 之外才能工作使用 pageX 和 pageY。

问题

是否有其他方法可以完成我想要完成的两件事之一?是否有其他方法使用 CSS 来隐藏/显示不在同一个 div 中的元素?或某种方式与 javascript?如果可能,我宁愿不使用 jQuery。我已经尝试为 mouSEOver 和 mouSEOut 添加一个事件侦听器,但它们触发不正确,如果我只是 console.log 任何事件,鼠标悬停会使它多次触发 mouSEOver 和 mouSEOut,这会导致它闪烁。有没有办法以像素为单位获得 content 的边缘距窗口左侧/顶部的距离?如果是这样,我可以从 pageX/pageY 中减去它,这可能会起作用。

顺便说一句,如果我正在做的某些事情似乎没有必要,或者我给出的描述不是您尝试查看 html 时发生的情况/无论什么,请告诉我,尽管它可能是因为原代码够长我就不贴在这里了,所以我试着做一个例子来说明同样的事情。

我不确定在这种情况下除了询问之外该怎么做,但像往常一样,可能有一些我没有想到的简单答案。我试图让这个问题比过去更清晰,所以希望它显示出来。提前感谢您的任何帮助!

编辑

我想我最好包含我用于我的项目的实际代码,以防我在示例代码中出错,或者忘记包含我没有意识到相关的内容https://codepen.io/fun840/pen/QWprQXy

编辑 2

正如@DavidsaysreinstateMonica 在评论中指出的那样,我没有在我的实际代码中(在 codepen 上)指定元素 A 和 B 是什么。元素 A 是 mainitem,元素 B 是 tooltip-border

解决方法

您可以将 pointer-events: none; 添加到 #B css。它会修复它,因为 B 将不再拦截鼠标事件。

let b = document.getElementById('B');

const onMouseMove = (e) =>{
  b.style.left = e.offsetX + 'px';
  b.style.top = e.offsetY + 'px';
}

document.addEventListener('mousemove',onMouseMove);
* {
 margin: 10px;
}

#content {
  position: absolute; /* Not needed in this example,but required for what I'm trying to make,I'm adding it because it might be relevant. */
  border: 5px solid green;
}

#A {
  border: 5px solid red;
  width: 500px;
  height: 500px;
}

#B {
  display: none;
  position: absolute;
  border: 5px solid blue;
  width: 100px;
  height: 100px;
  pointer-events:none;
}

#A:hover~#B {
  display: block;
}
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <div id="content">
      <div id="A"></div>
      <div id="B"></div>
    </div>
  </body>
  <script src="script.js"></script>
</html>