如何在div的位置添加事件监听器?

时间:2019-05-25 07:39:49

标签: javascript html css

当同一个div到达视口顶部时,我希望div的css属性更改。

特别是,我希望“ second-subdiv”只有在“ first-subdiv”到达视口顶部时才具有overflow: scroll

基本上,我想在“ second-subdiv”上设置overflow: hidden,然后写几行js,其中我会说:

add.EventListener(when-first-subdiv-is-on-top, change the overflow property)

<div class="first-div">
  <h1>Title</h1>
</div>

<div class= "second-div">
  <div class="first subdiv">
    <h1>You are Beautiful</h1>
  </div>
  <div class="second subdiv">
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
    <h2>Something Good</h2>
  </div>
</div>
html, body {
  margin: 0;
  padding: 0;
}
.first-div {
  margin: 0;
  width: 100%;
  height: 80vh;
  background-color: red;
  display: flex;
  justify-content: center;
  align-items: center;
  h1 {
    color: white;
  }
}
.second-div {
  display: flex;
  justify-content: space-around;
}
.subdiv {
  width: 50%;
  height: 100vh;
  text-align: center;
  overflow: scroll;
}
.first.subdiv {
  background-color: magenta;
}
.second.subdiv {

}

有什么帮助吗?

谢谢

Matteo

1 个答案:

答案 0 :(得分:1)

首先定义一个实现所需样式逻辑的函数。

free

函数const EPSILON = 0.5; function setOverflow () { var firstDiv = document.querySelector('.first.subdiv'); var secondDiv = document.querySelector('.second.subdiv'); var rect = firstDiv.getBoundingClientRect(); if (Math.abs(rect.top) < EPSILON) { secondDiv.style.overflow = 'scroll'; } else { secondDiv.style.overflow = 'hidden'; } } 将使用get​Bounding​Client​Rect来读取setOverflow的位置,并检查其.first.subdiv坐标是否足够接近零(即窗口的顶部边框),并相应地设置溢出样式属性。由于top坐标通常不会精确地为 0 ,因此{em>的公差足够接近0 ,因此,{ {1}}变量。

只要top元素的位置发生更改,此函数就必须运行,以便可以重新计算溢出属性。您至少需要以下事件:EPSILON.first.subdivload,但是根据最终结果,可能需要更多事件。例如,如果动态添加图像,则resize的位置可能会更改,而不会触发任何上述事件。您可能需要研究Dale Harris的建议,然后选择Intersection Observer API

为避免过多地重新计算溢出,请将函数调用包装在window.requestAnimationFrame中。

scroll

函数.first.subdiv将忽略对setOverflow的重复调用(如果已调用但未在动画帧中执行)。

只需将这两个代码部分包装在function maybeSetOverflow () { if (!setOverflow.isBusy) { setOverflow.isBusy = true; window.requestAnimationFrame(() => {setOverflow.isBusy = false; setOverflow()}); } } window.addEventListener('scroll', maybeSetOverflow); window.addEventListener('resize', maybeSetOverflow); window.addEventListener('load' , maybeSetOverflow); 中,然后将其放在maybeSetOverflow的底部即可。