我希望当桥元素在视区中时,运行1次css关键帧动画.Intersecuator在这方面做得很好,但问题是,当单击元素中具有onClicks的其他部分以显示新的文本段落时,动画会随机激发.

重点是唤起用户的注意,嘿!当Main元素出现在视图中时,您可以通过显示延迟框阴影来单击桥元素的这些部分.也许有一种更好的方式来向用户展示一个区域是可点击的,也许有一个JS规则我忽略了?如有任何建议,欢迎光临--谢谢!

示例: https://codepen.io/robyngraha/pen/LYaZMVg

function firstBro() {
  document.getElementById("first-bro-text").style.display = "block";
  document.getElementById("second-bro-text").style.display = "none";
  document.getElementById("third-bro-text").style.display = "none";
  document.getElementById("first-brother").classList.add("bridge-green");
  document.getElementById("second-brother").classList.remove("bridge-green");
  document.getElementById("third-brother").classList.remove("bridge-green");
}

function secondBro() {
  document.getElementById("first-bro-text").style.display = "none";
  document.getElementById("second-bro-text").style.display = "block";
  document.getElementById("third-bro-text").style.display = "none";
  document.getElementById("first-brother").classList.remove("bridge-green");
  document.getElementById("second-brother").classList.add("bridge-green");
  document.getElementById("third-brother").classList.remove("bridge-green");
}

function thirdBro() {
  document.getElementById("first-bro-text").style.display = "none";
  document.getElementById("second-bro-text").style.display = "none";
  document.getElementById("third-bro-text").style.display = "block";
  document.getElementById("first-brother").classList.remove("bridge-green");
  document.getElementById("second-brother").classList.remove("bridge-green");
  document.getElementById("third-brother").classList.add("bridge-green");
}

// animation
const bridge = document.querySelector('.bridge');
const secondBroEl = document.querySelector('#second-brother');
const thirdBroEl = document.querySelector('#third-brother');
const observer = new IntersectionObserver(entries => {
  secondBroEl.classList.toggle('animation', entries[0].isIntersecting);
  thirdBroEl.classList.toggle('animation2', entries[0].isIntersecting);
  console.log(entries)
});

observer.observe(bridge);
.scroll-container {
  max-width: 480px;
}


/* Bridge CSS */

.bridge-container {
  height: 65px;
  color: white;
  border-radius: 8px;
  display: flex;
  gap: 2px;
  justify-content: space-between;
  font-size: 1.3rem;
  background: black;
  cursor: pointer;
  background: linear-gradient(180deg, #28411F 20.31%, #000 100%);
}


/* center div */

#second-brother {
  font-size: 1.8rem;
  width: 80%;
  margin: 0 auto;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-left: black solid 2px;
  border-right: black solid 2px;
}

.animation {
  animation-name: highlight;
  animation-duration: 1s;
  animation-iteration-count: 1;
}

@keyframes highlight {
  0% {
    box-shadow: none;
  }
  50% {
    box-shadow: 0 0px 10px 10px orange;
  }
  100% {
    box-shadow: none;
  }
}


/* center changing text  */

#second-brother::after {
  content: "2nd";
  position: relative;
}


/* outer left div */

#first-brother {
  border-radius: 8px 0px 0px 8px;
  width: 20%;
  height: 65px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 20px;
  font-size: 1.5rem;
}


/* outer left div text */

#first-brother::after {
  content: "1st";
  position: relative;
}


/* outer right div */

#third-brother {
  border-radius: 0px 8px 8px 0px;
  width: 20%;
  height: 65px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 20px;
  font-size: 1.5rem;
}

.animation2 {
  animation-name: highlight2;
  animation-delay: .5s;
  animation-duration: 1s;
  animation-iteration-count: 1;
}

@keyframes highlight2 {
  0% {
    box-shadow: none;
  }
  50% {
    box-shadow: 0 0px 10px 10px orange;
  }
  100% {
    box-shadow: none;
  }
}


/* outer right div text */

#third-brother::after {
  content: "3rd";
  position: relative;
}

@media (max-width: 625px) {
  #first-brother-left::after {
    margin-left: 12px;
  }
}

@media (max-width: 480px) {
  #countdown-right,
  #countdown-left,
  #center-battery {
    font-size: 1rem;
  }
}


/* Brothers text */

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

#first-bro-text {
  display: block;
  animation: fadeIn .5s;
}

#second-bro-text {
  display: none;
  animation: fadeIn .5s;
}

#third-bro-text {
  display: none;
  animation: fadeIn .5s;
}

.bridge-green {
  background: linear-gradient(180deg, #4A7938 20.31%, #000 100%);
  animation: fadeIn 1s;
}
<div class="scroll-container">
  <!-- For Spacing -->
  <h1>Scroll down....<br />Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus architecto voluptatem numquam, nihil ullam suscipit, odit placeat labore natus maxime laborum aliquam voluptates animi, dicta facere debitis earum beatae nemo.
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Rem totam aut fugiat nostrum animi, sed illum ad minima sint sequi nemo, labore, suscipit et reiciendis fuga corrupti! Provident, tempore ab. Lorem ipsum dolor sit amet consectetur adipisicing
    elit. Reiciendis enim ad quos incidunt culpa necessitatibus eveniet aut earum quia, est iste debitis eos quidem facilis facere? Velit temporibus esse adipisci?</h1>

  <div class="bridge-container bridge">
    <div id="first-brother" class="bridge-green" onclick="firstBro()"></div>
    <div id="second-brother" onclick="secondBro()"></div>
    <div id="third-brother" onclick="thirdBro()"></div>
    <div id="rmg">HELLO</div>
  </div>

  <div id="first-bro-text">
    <p style="color:#225BBE;font-weight:900;">First Brother</p>
    <p>So, the oldest brother, who was a combative man, asked for a wand more powerful than any in existence. A wand that must always win battles for its owner. A wand worthy of a wizard who had conquered Death. So, Death had crossed to an Elder Tree on
      the banks of the river, fashioned a wand from a branch that had hung there, and gave it to the oldest brother</p>
  </div>
  <div id="second-bro-text">
    <p style="color:#225BBE;font-weight:900;">Second Brother</p>
    <p>Then the second brother, who was an arrogant man, decided that he wanted to humiliate Death still further, and asked for the power to recall others from Death. So, Death picked up a stone from the riverbank and gave it to the second brother, and told
      him that the stone would have the power to bring back the dead.</p>
  </div>
  <div id="third-bro-text">
    <p style="color:#225BBE;font-weight:900;">Third Brother</p>
    <p>Finally, Death turned to the third brother. A humble man, he asked for something that would enable him to go forth from that place without being followed by Death. And so it was that Death reluctantly handed over his own Cloak of Invisibility. </p>
  </div>

  <div id="click-me">Click Me</div>
  <!-- For Spacing -->
  <h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus architecto voluptatem numquam, nihil ullam suscipit, odit placeat labore natus maxime laborum aliquam voluptates animi, dicta facere debitis earum beatae nemo. Lorem ipsum dolor sit
    amet consectetur adipisicing elit. Rem totam aut fugiat nostrum animi, sed illum ad minima sint sequi nemo, labore, suscipit et reiciendis fuga corrupti! Provident, tempore ab. Lorem ipsum dolor sit amet consectetur adipisicing elit. Reiciendis enim
    ad quos incidunt culpa necessitatibus eveniet aut earum quia, est iste debitis eos quidem facilis facere? Velit temporibus esse adipisci?</h1>

</div>

我try 在css中将Animation-Iteration-Count设置为1,但每当单击具有onClick功能的第一、第二或第三个元素时,动画就会重新开始.

我在INTERSECT观察元素之外添加了一个onClick函数,动画不会运行,因此它必须与具有INTERSECT观察器的元素相关.

我添加了一个元素,在没有onclick(Hello文本)的交叉点观察器中,动画不会触发,所以问题必须与onclick元素有关.

推荐答案

该问题是由animationanimation2类以及bridge-green类导致的,这两个类都有动画.只要您的元素进入视线,就会播放highlight个动画.然后,当您单击时,添加bridge-green类并覆盖动画.再次移除bridge-green类将再次触发highlight动画.

一种解决方案是扩展相交观察者逻辑,当元素进入视图时只添加一次animation类,然后停止观察.这将防止多次添加animation类.

然后在动画结束后使用animationend删除animation类,以便bridge-green可以在animation不妨碍的情况下完成它的工作.

function firstBro() {
  document.getElementById("first-bro-text").style.display = "block";
  document.getElementById("second-bro-text").style.display = "none";
  document.getElementById("third-bro-text").style.display = "none";
  document.getElementById("first-brother").classList.add("bridge-green");
  document.getElementById("second-brother").classList.remove("bridge-green");
  document.getElementById("third-brother").classList.remove("bridge-green");
}

function secondBro() {
  document.getElementById("first-bro-text").style.display = "none";
  document.getElementById("second-bro-text").style.display = "block";
  document.getElementById("third-bro-text").style.display = "none";
  document.getElementById("first-brother").classList.remove("bridge-green");
  document.getElementById("second-brother").classList.add("bridge-green");
  document.getElementById("third-brother").classList.remove("bridge-green");
}

function thirdBro() {
  document.getElementById("first-bro-text").style.display = "none";
  document.getElementById("second-bro-text").style.display = "none";
  document.getElementById("third-bro-text").style.display = "block";
  document.getElementById("first-brother").classList.remove("bridge-green");
  document.getElementById("second-brother").classList.remove("bridge-green");
  document.getElementById("third-brother").classList.add("bridge-green");
}

// animation
const bridge = document.querySelector('.bridge');
const secondBroEl = document.querySelector('#second-brother');
const thirdBroEl = document.querySelector('#third-brother');

const observer = new IntersectionObserver((entries, observer) => {
  for (const { isIntersecting } of entries) {
    if (isIntersecting) {
      secondBroEl.classList.add('animation');
      thirdBroEl.classList.add('animation');
      
      observer.unobserve(bridge);
    }
  }
});

observer.observe(bridge);

secondBroEl.addEventListener('animationend', removeAnimationAfterFinish);
thirdBroEl.addEventListener('animationend', removeAnimationAfterFinish);

function removeAnimationAfterFinish(event) {
  event.target.classList.remove('animation');
}
.scroll-container {
  max-width: 480px;
}


/* Bridge CSS */

.bridge-container {
  height: 65px;
  color: white;
  border-radius: 8px;
  display: flex;
  gap: 2px;
  justify-content: space-between;
  font-size: 1.3rem;
  background: black;
  cursor: pointer;
  background: linear-gradient(180deg, #28411F 20.31%, #000 100%);
}


/* center div */

#second-brother {
  font-size: 1.8rem;
  width: 80%;
  margin: 0 auto;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-left: black solid 2px;
  border-right: black solid 2px;
}

#second-brother.animation {
  animation-name: highlight;
  animation-duration: 1s;
}

@keyframes highlight {
  0% {
    box-shadow: none;
  }
  50% {
    box-shadow: 0 0px 10px 10px orange;
  }
  100% {
    box-shadow: none;
  }
}


/* center changing text  */

#second-brother::after {
  content: "2nd";
  position: relative;
}


/* outer left div */

#first-brother {
  border-radius: 8px 0px 0px 8px;
  width: 20%;
  height: 65px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 20px;
  font-size: 1.5rem;
}


/* outer left div text */

#first-brother::after {
  content: "1st";
  position: relative;
}


/* outer right div */

#third-brother {
  border-radius: 0px 8px 8px 0px;
  width: 20%;
  height: 65px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 20px;
  font-size: 1.5rem;
}

#third-brother.animation {
  animation-name: highlight;
  animation-delay: .5s;
  animation-duration: 1s;
}


/* outer right div text */

#third-brother::after {
  content: "3rd";
  position: relative;
}

@media (max-width: 625px) {
  #first-brother-left::after {
    margin-left: 12px;
  }
}

@media (max-width: 480px) {
  #countdown-right,
  #countdown-left,
  #center-battery {
    font-size: 1rem;
  }
}


/* Brothers text */

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

#first-bro-text {
  display: block;
  animation: fadeIn .5s;
}

#second-bro-text {
  display: none;
  animation: fadeIn .5s;
}

#third-bro-text {
  display: none;
  animation: fadeIn .5s;
}

.bridge-green {
  background: linear-gradient(180deg, #4A7938 20.31%, #000 100%);
  animation: fadeIn 1s;
}
<div class="scroll-container">
  <!-- For Spacing -->
  <h1>Scroll down....<br />Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus architecto voluptatem numquam, nihil ullam suscipit, odit placeat labore natus maxime laborum aliquam voluptates animi, dicta facere debitis earum beatae nemo.
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Rem totam aut fugiat nostrum animi, sed illum ad minima sint sequi nemo, labore, suscipit et reiciendis fuga corrupti! Provident, tempore ab. Lorem ipsum dolor sit amet consectetur adipisicing
    elit. Reiciendis enim ad quos incidunt culpa necessitatibus eveniet aut earum quia, est iste debitis eos quidem facilis facere? Velit temporibus esse adipisci?</h1>

  <div class="bridge-container bridge">
    <div id="first-brother" class="bridge-green" onclick="firstBro()"></div>
    <div id="second-brother" onclick="secondBro()"></div>
    <div id="third-brother" onclick="thirdBro()"></div>
    <div id="rmg">HELLO</div>
  </div>

  <div id="first-bro-text">
    <p style="color:#225BBE;font-weight:900;">First Brother</p>
    <p>So, the oldest brother, who was a combative man, asked for a wand more powerful than any in existence. A wand that must always win battles for its owner. A wand worthy of a wizard who had conquered Death. So, Death had crossed to an Elder Tree on
      the banks of the river, fashioned a wand from a branch that had hung there, and gave it to the oldest brother</p>
  </div>
  <div id="second-bro-text">
    <p style="color:#225BBE;font-weight:900;">Second Brother</p>
    <p>Then the second brother, who was an arrogant man, decided that he wanted to humiliate Death still further, and asked for the power to recall others from Death. So, Death picked up a stone from the riverbank and gave it to the second brother, and told
      him that the stone would have the power to bring back the dead.</p>
  </div>
  <div id="third-bro-text">
    <p style="color:#225BBE;font-weight:900;">Third Brother</p>
    <p>Finally, Death turned to the third brother. A humble man, he asked for something that would enable him to go forth from that place without being followed by Death. And so it was that Death reluctantly handed over his own Cloak of Invisibility. </p>
  </div>

  <div id="click-me">Click Me</div>
  <!-- For Spacing -->
  <h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Temporibus architecto voluptatem numquam, nihil ullam suscipit, odit placeat labore natus maxime laborum aliquam voluptates animi, dicta facere debitis earum beatae nemo. Lorem ipsum dolor sit
    amet consectetur adipisicing elit. Rem totam aut fugiat nostrum animi, sed illum ad minima sint sequi nemo, labore, suscipit et reiciendis fuga corrupti! Provident, tempore ab. Lorem ipsum dolor sit amet consectetur adipisicing elit. Reiciendis enim
    ad quos incidunt culpa necessitatibus eveniet aut earum quia, est iste debitis eos quidem facilis facere? Velit temporibus esse adipisci?</h1>

</div>

Javascript相关问答推荐

React:未调用useState变量在调试器的事件处理程序中不可用

从实时数据库(Firebase)上的子类别读取数据

调用removeEvents不起作用

useNavigation更改URL,但不呈现或显示组件

在Angular中将样式应用于innerHTML

有没有可能使滑动img动画以更快的速度连续?

如何将react—flanet map添加到remixjs应用程序

加载背景图像时同步旋转不显示的问题

还原器未正确更新状态

使用NextJS+MongoDB+Prisma ORM获取无效请求正文,无法发布错误

是否可以将Select()和Sample()与Mongoose结合使用?

对具有相似属性的对象数组进行分组,并使用串连的值获得结果

如何在一个对象Java脚本中获取不同键的重复值?

使用CEPRESS截取时,cy.Wait()在等待5000ms的第一个路由请求时超时

如何在下一个js中更改每个标记APEXCHARTS图表的 colored颜色

如何在TransformControls模式下只保留箭头进行翻译?

递增/递减按钮React.js/Redux

为什么当雪碧的S在另一个函数中时,Phaser不能加载它?

Playwright:ReferenceError:browserContext未定义

如何使用Angular JS双击按钮