问题描述
目标
正如标题所说,我想有两个元素,元素 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>