Search code examples
javascriptreactjsscroll

Play/Pause video onScroll in Reactjs


I'm trying to achieve a functionality where on scrolling a video gets paused if it was playing and vice versa. Currently I can do it with an onClick function that sets the state true/false. But the problem is that the video keeps on playing after scrolling down till I don't click it to pause again. I want to keep the onClick feature as it is and also want to add the onScroll feature. Tried doing it with onScroll but not working.

const [playing, setPlaying] = useState(false);
  const videoRef = useRef(null);

  const handleVideoPress = () => {
    if (playing) {
      videoRef.current.pause();
      setPlaying(false);
    } else {
      videoRef.current.play();
      setPlaying(true);
    }
  };
  return (
    <div className="video">
      <video
        onClick={handleVideoPress}
        className="video__player"
        loop
        ref={videoRef}
        src={url}
      ></video>
    );
}

Solution

  • So this will stop your video from playing on any scroll event. If you want it to stop playing if it has left the viewport you can look into using something like the IntersectionObserver API to do something if it is in the viewport (play the video) or outside of the viewport (stop the video).

    Note: most modern browsers won't allow Javascript to start a video unless there has been at least some user interaction with the page already.

      const [playing, setPlaying] = useState(false);
      const videoRef = useRef(null);
    
      useEffect(() => {
        window.addEventListener('scroll', debounce(handleScroll, 200))
    
        return () => {
          window.removeEventListener('scroll', handleScroll);
        };
      }, []}
    
      const startVideo = () => {
        videoRef.current.pause();
        setPlaying(false);
      }
    
      const pauseVideo = () => {
        videoRef.current.play();
        setPlaying(true);
      }
    
      const handleScroll = (e) => {
        if (playing) {
          pauseVideo();
        }
      }
    
      const handleVideoPress = () => {
        if (playing) {
          startVideo();
        } else {
          pauseVideo();
        }
      };
    
      return (
        <div className="video">
          <video
            onClick={handleVideoPress}
            className="video__player"
            loop
            ref={videoRef}
            src={url}
          ></video>
        );
    }
    

    I made a working example of using the IntersectionObserver with React's ref hooks which can be found here:

    https://codesandbox.io/s/strange-smoke-p9hmx

    Please let me know if you have any more questions.