Home > OS >  How to set ScrollToTop Button to be active on viewport height?
How to set ScrollToTop Button to be active on viewport height?

Time:07-12

At the moment i am using hardcoded height point to trigger visible ScrollToTop Button. i would love to get solution to be triggered when passing viewport height.

  const { scrollDirection } = useScrollDirection()
  const { scrollPosition } = useScrollPosition()
  const [isVisible, setIsVisible] = useState(false)
  const toggleVisible = () => {
    if (scrollPosition === 0) {
      setIsVisible(false)
    }
    **if (scrollPosition > 800) {
      setIsVisible(true)
    } else if (scrollPosition <= 799) {
      setIsVisible(false)
    }**
  }
  const scrollToTop = () => {
    window.scrollTo({
      top: 0,
      behavior: "smooth",
    })
  }
  window.addEventListener("scroll", toggleVisible)

CodePudding user response:

You can do this by using Intersection Observer (IO)

First you create an element that is just below the viewport initially. And whenever this element comes into view, show the button.

This requires one dummy element which you observe, for the demo I set the html element to position: relative for it to work. Maybe you can use a different element structure, based on your html. Important thing is that you have one element you can observe and trigger the element depending on when it comes into view.

let options = {
  rootMargin: '0px',
  threshold: 0.1 // when at least 10% of the element is visible we show the button
}

const callback = (entries, observer) => {
  const btn = document.querySelector('#scroll-top');
  entries.forEach(entry => {
    if (entry.intersectionRatio > 0.1) {
      // if we are past our 0.1 threshold we show the button
      btn.classList.add('visible')
    } else {
      // otherwise we hide the button
      btn.classList.remove('visible')
    }
  });
};

const observer = new IntersectionObserver(callback, options);

const target = document.querySelector('#button-trigger');
observer.observe(target);
.dummy-viewport {
  min-height: 400vh;
}

html {
  position: relative;
}

#button-trigger {
  position: absolute;
  top: 100vh;
  left: 10px;
  height: calc(100% - 100vh);
  /* for demo purposes, don't show the element on the finished site*/
  width: 2rem;
  outline: 1px solid rebeccapurple;
  writing-mode: vertical-rl;
  text-orientation: mixed;
}

p {
  padding: 0;
  margin: 0;
}

#scroll-top {
  position: fixed;
  bottom: 40px;
  right: 10px;
  opacity: 0;
  transition: .5s opacity;
}

#scroll-top.visible {
  opacity: 1
}
<div >
  <p> Scroll down ↓ </p>

  <button id="scroll-top" type="button"> Scroll to top </button>

</div>

<div id="button-trigger">
  <p> When I am visible, I show the button </p>
</div>

CodePudding user response:

you can use window.innerHeight

const toggleVisible = () => {
    const viewportHeight = window.innerHeight;
    if (scrollPosition === 0) {
        setIsVisible(false)
    }
    **if (scrollPosition > viewportHeight) {
        setIsVisible(true)
    } else if (scrollPosition <= viewportHeight) {
        setIsVisible(false)
    }**
}
  • Related