最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I get CSS scroll snap to work with JS scroll event listener? - Stack Overflow

programmeradmin4浏览0评论

I am working on this project where I need both scroll listeners and scroll-snapping, so I can make some cool transition effects between section changes.

I could get both of these to work separately, but not together. Scroll snapping requires a container element (main element) to have a height, but when I give it a height: 100%, JavaScript scroll listener stops working.

I tried everything I know, tried changing other containers' height/overflow properties and tried targeting other elements than body or window. What would be the best workaround be?

The snippet here is adjusted to work with listener at the moment. If you go ahead and add height: 100% to main, you will see that scroll snapping starts working, but the event listener breaks.

const scrollEvent = () => {
  const main = document.querySelector('#main');
  const section1 = document.querySelector('#sect1');
  const section2 = document.querySelector('#sect2');

  if (main.scrollTop > 50) {
    section1.style.backgroundColor = "red";

  } else {
    section1.style.backgroundColor = "pink";
  }

  if (main.scrollTop > window.innerHeight / 2) {
    section2.style.backgroundColor = "blue";
  } else {
    section2.style.backgroundColor = "purple";
  }
}


window.addEventListener('scroll', scrollEvent);
* {
  padding: 0;
  margin: 0;
}

html,
body {
  height: 100%;
  width: 100%;
}

body {
  scroll-behavior: smooth;
}

main {
  display: flex;
  flex-direction: column;
  width: 100vw;
  overflow: auto;
  scroll-snap-type: y mandatory;
}

section {
  flex-basis: 100vh;
  flex-grow: 1;
  flex-shrink: 0;
  width: 90vw;
  border: 1px solid red;
  margin: 0 auto;
}

main section {
  scroll-snap-align: start;
}
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
  <main id="main" dir="ltr">
    <section id="sect1">
      <h1>content1</h1>
    </section>
    <section id="sect2">
      <h1>content2</h1>
    </section>
  </main>
</body>

</html>

I am working on this project where I need both scroll listeners and scroll-snapping, so I can make some cool transition effects between section changes.

I could get both of these to work separately, but not together. Scroll snapping requires a container element (main element) to have a height, but when I give it a height: 100%, JavaScript scroll listener stops working.

I tried everything I know, tried changing other containers' height/overflow properties and tried targeting other elements than body or window. What would be the best workaround be?

The snippet here is adjusted to work with listener at the moment. If you go ahead and add height: 100% to main, you will see that scroll snapping starts working, but the event listener breaks.

const scrollEvent = () => {
  const main = document.querySelector('#main');
  const section1 = document.querySelector('#sect1');
  const section2 = document.querySelector('#sect2');

  if (main.scrollTop > 50) {
    section1.style.backgroundColor = "red";

  } else {
    section1.style.backgroundColor = "pink";
  }

  if (main.scrollTop > window.innerHeight / 2) {
    section2.style.backgroundColor = "blue";
  } else {
    section2.style.backgroundColor = "purple";
  }
}


window.addEventListener('scroll', scrollEvent);
* {
  padding: 0;
  margin: 0;
}

html,
body {
  height: 100%;
  width: 100%;
}

body {
  scroll-behavior: smooth;
}

main {
  display: flex;
  flex-direction: column;
  width: 100vw;
  overflow: auto;
  scroll-snap-type: y mandatory;
}

section {
  flex-basis: 100vh;
  flex-grow: 1;
  flex-shrink: 0;
  width: 90vw;
  border: 1px solid red;
  margin: 0 auto;
}

main section {
  scroll-snap-align: start;
}
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
  <main id="main" dir="ltr">
    <section id="sect1">
      <h1>content1</h1>
    </section>
    <section id="sect2">
      <h1>content2</h1>
    </section>
  </main>
</body>

</html>

Share Improve this question edited May 7, 2022 at 19:26 Peter Mortensen 31.6k22 gold badges110 silver badges133 bronze badges asked May 12, 2020 at 20:36 Özenç B.Özenç B. 1,0383 gold badges10 silver badges28 bronze badges 2
  • The specific problem is overflow: auto; on main. getting rid of that allows it to work. – imvain2 Commented May 12, 2020 at 20:57
  • I don't see how. With overflow: auto gone scroll snaps do not work – Özenç B. Commented May 12, 2020 at 21:00
Add a ment  | 

1 Answer 1

Reset to default 12

In another topic @lawrence-witt stated that I had to add the event listener to main, instead of whole window. With main.addEventListener('scroll', scrollEvent); both scroll snap and scroll event listener work fine.

const scrollEvent = () => {
  const main = document.querySelector('#main');
  const section1 = document.querySelector('#sect1');
  const section2 = document.querySelector('#sect2');

  if (main.scrollTop > 50) {
    section1.style.backgroundColor = "red";

  } else {
    section1.style.backgroundColor = "pink";
  }

  if (main.scrollTop > window.innerHeight / 2) {
    section2.style.backgroundColor = "blue";
  } else {
    section2.style.backgroundColor = "purple";
  }
}


main.addEventListener('scroll', scrollEvent);
* {
  padding: 0;
  margin: 0;
}

html,
body {
  height: 100%;
  width: 100%;
}

body {
  scroll-behavior: smooth;
}

main {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100%;
  overflow: auto;
  scroll-snap-type: y mandatory;
}

section {
  flex-basis: 100vh;
  flex-grow: 1;
  flex-shrink: 0;
  width: 90vw;
  border: 1px solid red;
  margin: 0 auto;
}

main section {
  scroll-snap-align: start;
}
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
  <main id="main" dir="ltr">
    <section id="sect1">
      <h1>content1</h1>
    </section>
    <section id="sect2">
      <h1>content2</h1>
    </section>
  </main>
</body>

</html>

发布评论

评论列表(0)

  1. 暂无评论