简体   繁体   English

JavaScript 事件侦听器的问题

[英]trouble with JavaScript event listeners

I have a div container with three normal divs inside and three absolutely positioned divs that lie below the normal other three, so six divs in total and a little bit of paragraph text.我有一个 div 容器,里面有三个正常的 div 和三个绝对定位的 div,它们位于正常的其他三个 div 之下,所以总共有六个 div 和一些段落文本。 what i am going for is when i hover on each of the three normal divs, the paragraph and the absolutely positioned divs to come on top and when it is not hovered, the normal divs to be on top.我要做的是当我在三个普通 div 中的每一个上设置 hover 时,段落和绝对定位的 div 出现在顶部,当它没有悬停时,普通 div 出现在顶部。 i have got it almost working, it is just unreliable.我几乎可以正常工作了,只是不可靠。

 const allDivs = document.getElementsByClassName("content"); const allOverlays = document.getElementsByClassName("overlay"); const details = document.getElementsByClassName("details"); const showOverlays = (e) => { let target = e.target.className; let index = parseInt(target[3]); allOverlays[index].style.zIndex = '2'; details[index].style.display = 'block'; } const hideOverlays = (e) => { let target = e.target.className; let index = parseInt(target[7]); allOverlays[index].style.zIndex = '-1'; details[index].style.display = 'none'; } for(let i=0; i < 3; i++){ allDivs[i].addEventListener('mouseover', showOverlays) } for(let i=0; i < 3; i++){ allOverlays[i].addEventListener('mouseout', hideOverlays) }
 * { margin: 0; padding: 0; box-sizing: border-box; }.container { width: 70vw; height: 50vh; display: grid; grid-template-columns: repeat(3,1fr); background-color: blue; gap: 10vw; margin: 20vh auto; position: relative; overflow: hidden; }.content { width: 100%; height: 100%; background-color: black; }.overlay { width: 220px; height: 100%; position: absolute; background-color: brown; z-index: -1; }.overlay1, .det1 { left: 26.7vw; }.overlay2, .det2 { left: 53.5vw; }.details { position: absolute; color: white; display: none; z-index: 5; }
 <body> <div class="container"> <div class="overlay0 overlay" ></div> <div class="div0 content"></div> <div class="det0 details"> <p>details</p> <p>details</p> </div> <div class="overlay1 overlay"></div> <div class="div1 content"></div> <div class="det1 details"> <p>details</p> <p>details</p> </div> <div class="overlay2 overlay"></div> <div class="div2 content"></div> <div class="det2 details"> <p>details</p> <p>details</p> </div> </div> </body>

In your case the problem is in the mouseleave event and the details element, I will explain the reason of the weird behavior:在您的情况下,问题出在mouseleave事件和details元素中,我将解释奇怪行为的原因:

  1. this only happens when the cursor goes over the details element只有当 cursor 遍历 details 元素时才会发生这种情况
  2. when the cursor goes over the P element a mouse leave event is triggered and right after a mouse enter/over event is triggered当 cursor 越过P元素时,会触发鼠标离开事件,并在触发鼠标进入/悬停事件后立即触发
  3. as the P element has no margin and is overlapping the overlay div so when your cursor leaves the P element towards to another div the mouse leave event is not triggered, and that's the reason why the overlay stays after leaving the div.由于P元素没有边距并且与覆盖 div重叠,因此当您的 cursor 将P元素移向另一个 div 时,不会触发鼠标离开事件,这就是为什么在离开 div 后覆盖仍然存在的原因。 So keep in mind that the edges of your overlay div should not be overlapped by any other div if you want the leave event to be triggered因此请记住,如果您希望触发离开事件,则覆盖 div 的边缘不应与任何其他 div 重叠

a workaround for this is add a margin to details class and increase the width size of the container class, like so:解决方法是为细节 class添加边距并增加容器 class 的宽度大小,如下所示:

.container {
  width: 75vw; /* increased to 75 */
  height: 50vh;
  display: grid;
  grid-template-columns: repeat(3,1fr);
  background-color: blue;
  gap: 10vw;
  margin: 20vh auto;
  position: relative;
  overflow: hidden;
}

.details {
  margin: 15px; /* added margin */
  position: absolute;
  color: white;
  display: none;
  z-index: 5;
}

but this is not a definitive solution, as the problem should appears again if you change the styles.但这不是最终的解决方案,因为如果您更改 styles,问题应该会再次出现。

what I did on my project was add a condition in the mouse leave event, something like this:我在我的项目中所做的是在鼠标离开事件中添加一个条件,如下所示:

const hideElement = (e) => {
  if(e.relatedTarget === "someOuterDiv") {
    // close the element
  }
}

in the example above the event is only triggered if the cursor goes towards an outer div, but unfortunately this will not work in your case as you have sibling elements that need to be closed too.在上面的示例中,事件仅在 cursor 朝向外部 div 时触发,但不幸的是,这在您的情况下不起作用,因为您也有需要关闭的兄弟元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM