首页 > 解决方案 > 使用js为某些类的元素滚动动画

问题描述

我正在尝试为 class 的每个元素制作滚动动画js-scroll。在样式代码中,我有一个.scrolled-proj将项目的不透明度从 0 更改为 1 的类。js-scroll当每个元素出现在窗口中时(在 100 像素内,基于偏移输入),js 代码将这个类添加到每个元素。我的代码的相关位如下:

const scroll_elem = document.querySelectorAll(".js-scroll");
scroll_elem.forEach( (el) => {el.style.opacity = "0";} );

// returns true if elem is "in view"
const in_view = (el, off) => {
    const top = el.getBoundingClientRect().top;
    return ( top <= (window.innerHeight - offset) );
}

const scroll_animation = () => {
    scroll_elem.forEach((el) => {
        if(in_view(el, 100)){ el.classList.add("scrolled-proj"); }
        else{ el.classList.remove("scrolled-proj"); }
    })
}

window.addEventListener("scroll", () => { 
    scroll_animation();
});
.project-elem {
    background-color: greenyellow;
    margin: 5rem 5rem;
    --height: 300px;
}

.projects {
    margin: 0;
    padding: 3rem;
    background-color: #DDCDE8;
    font: Asap, sans-serif;
    height: 5*var(--height);
    text-align: center;
}

.project-n {
    background-color: green;
    text-align: center;
    width: 60%;
    height: 250px;
    float: left;
    padding: 3rem;
}

.img {
    background-color: blue;
    text-align: center;
    margin-left: 40%;
    height: 250px;
}

.scrolled-proj{
    opacity: 1;
}
<div class="projects" id=#projects>
  <h2>My Projects</h2>

  <article class="project-elem">
      <div class="project-n js-scroll" id="dictocounter">
          <h3>Dictation Counter</h3>
          <p>info about proj</p>
          <img src="dictocounter1.jpg" alt="Dictocounter in Action">
      </div>
      <div class="img js-scroll">
          <p>heres SOME IMAGE</p>
      </div>
  </article>

  <article class="project-elem">
      <div class="project-n js-scroll" id="calc">
          <h3>RPN Calculator</h3>
          <p>info about proj</p>
          <img src="calc.jpg" alt="RPN Calculator Decoding Input">
      </div>
      <div class="img js-scroll">
          <p>heres SOME IMAGE</p>
      </div>
  </article>

  <article class="project-elem">
      <div class="project-n js-scroll" id="markov">
          <h3>Markov Chain Text Generation</h3>
          <p>info about proj</p>
          <img src="calc.jpg" alt="Markov Chain Text Generation">
      </div>
      <div class="img js-scroll">
          <p>heres SOME IMAGE</p>
      </div>
  </article>

  <article class="project-elem">
      <div class="project-n js-scroll" id="audio">
          <h3>Song Similarities</h3>
          <p>info about proj</p>
          <img src="calc.jpg" alt="Audio Spectral Analysis">
      </div>
      <div class="img js-scroll">
          <p>heres SOME IMAGE</p>
      </div>
  </article>

  <article class="project-elem">
      <div class="project-n js-scroll" id="tree">
          <h3>DFS/BFS Search Tree</h3>
          <p>info about proj</p>
          <img src="calc.jpg" alt="Simple Trees">
      </div>
      <div class="img js-scroll">
          <p>heres SOME IMAGE</p>
      </div>
  </article>  
</div>
    

刷新网页后,每个 js-scroll 元素确实初始化为 opacity 0,但滚动不会改变任何 js-scroll 元素的不透明度。作为健全性检查,我让in_view函数始终返回 true,但所有 js-scroll 元素保持透明。这似乎表明scroll_animation没有被调用(因为in_view没有改变任何元素的不透明度),但我不知道为什么会这样。

标签: javascripthtmljquerycss

解决方案


几个问题。

您将参数 off传递给in_view() 函数,但是函数return语句引用offset的是未定义的。

然后,您在forEach循环中使用 JS为不透明度为 0的元素放置内联样式。该内联样式将在添加时覆盖来自该类的计算样式,因此无论添加将 opacity 属性定义为 1 的类,您的不透明度都不会实际设置为 1 .js-scroll

测试:首先修复您的参数命名问题并将函数中的返回重命名为,然后您可以运行您的滚动事件,然后查看检查器,它将与类一起在内联样式属性中,这是假设的将不透明度更改为 1。in_viewoffstyle="opacity:0;scrolled-proj

要解决此问题,请创建一个辅助css 规则,该规则使用而不是使用 javascript 创建的内联样式来初始化 opacity 属性。

因此,更改in_view函数以引用正确的参数,off然后添加一个将不透明度设置为 0 的 CSS 类。=> 一个类到初始循环中,它像这样遍历.js-scroll元素...

// reference the proper param in your return here
const in_view = (el, off) => {
  const top = el.getBoundingClientRect().top;
  return (top <= (window.innerHeight - off));
}
/* add a helper class that will set your opacity to 0 intially */
.scrolled-proj-hidden {
  opacity: 0;
  transition: opacity 500ms linear; /* optional .5 second animation for opacity */

然后JS

// Now instead of inline style, we add the helper class using el.classList.add()
const scroll_elem = document.querySelectorAll(".js-scroll");
scroll_elem.forEach((el) => {
  el.classList.add("scrolled-proj-hidden");
});

然后在你的scroll_animation函数上在你的条件中设置适当的类,就像这样......

const scroll_animation = () => {
  scroll_elem.forEach((el) => {
    if (in_view(el, 100)) {
      el.classList.add("scrolled-proj");
      el.classList.remove("scrolled-proj-hidden");
    } else {
      el.classList.remove("scrolled-proj");
      el.classList.add("scrolled-proj-hidden");
    }
  })
}

const scroll_elem = document.querySelectorAll(".js-scroll");
scroll_elem.forEach((el) => {
  el.classList.add("scrolled-proj-hidden");
});

// returns true if elem is "in view"
const in_view = (el, off) => {
  const top = el.getBoundingClientRect().top;
  return (top <= (window.innerHeight - off));
}

const scroll_animation = () => {
  scroll_elem.forEach((el) => {
    if (in_view(el, 100)) {
      el.classList.add("scrolled-proj");
      el.classList.remove("scrolled-proj-hidden");
    } else {
      el.classList.remove("scrolled-proj");
      el.classList.add("scrolled-proj-hidden");
    }
  })
}

window.addEventListener("scroll", scroll_animation);
.project-elem {
  background-color: greenyellow;
  margin: 5rem 5rem;
  --height: 300px;
}

.projects {
  margin: 0;
  padding: 3rem;
  background-color: #DDCDE8;
  font: Asap, sans-serif;
  height: 5*var(--height);
  text-align: center;
}

.project-n {
  background-color: green;
  text-align: center;
  width: 60%;
  height: 250px;
  float: left;
  padding: 3rem;
}

.img {
  background-color: blue;
  text-align: center;
  margin-left: 40%;
  height: 250px;
}

.scrolled-proj {
  opacity: 1;
  transition: opacity 500ms linear;
}

.scrolled-proj-hidden {
  opacity: 0;
  transition: opacity 500ms linear;
}
<div class="projects" id=#projects>
  <h2>My Projects</h2>

  <article class="project-elem">
    <div class="project-n js-scroll" id="dictocounter">
      <h3>Dictation Counter</h3>
      <p>info about proj</p>
      <img src="dictocounter1.jpg" alt="Dictocounter in Action">
    </div>
    <div class="img js-scroll">
      <p>heres SOME IMAGE</p>
    </div>
  </article>

  <article class="project-elem">
    <div class="project-n js-scroll" id="calc">
      <h3>RPN Calculator</h3>
      <p>info about proj</p>
      <img src="calc.jpg" alt="RPN Calculator Decoding Input">
    </div>
    <div class="img js-scroll">
      <p>heres SOME IMAGE</p>
    </div>
  </article>

  <article class="project-elem">
    <div class="project-n js-scroll" id="markov">
      <h3>Markov Chain Text Generation</h3>
      <p>info about proj</p>
      <img src="calc.jpg" alt="Markov Chain Text Generation">
    </div>
    <div class="img js-scroll">
      <p>heres SOME IMAGE</p>
    </div>
  </article>

  <article class="project-elem">
    <div class="project-n js-scroll" id="audio">
      <h3>Song Similarities</h3>
      <p>info about proj</p>
      <img src="calc.jpg" alt="Audio Spectral Analysis">
    </div>
    <div class="img js-scroll">
      <p>heres SOME IMAGE</p>
    </div>
  </article>

  <article class="project-elem">
    <div class="project-n js-scroll" id="tree">
      <h3>DFS/BFS Search Tree</h3>
      <p>info about proj</p>
      <img src="calc.jpg" alt="Simple Trees">
    </div>
    <div class="img js-scroll">
      <p>heres SOME IMAGE</p>
    </div>
  </article>
</div>

如果这不是您想要的,请告诉我,我可以编辑或删除此答案。


推荐阅读