How to stop Vimeo video playing when element hidden?

Hello! I’ve built a simple animation that makes my videos pop up when you click on the thumbnail. I’m using the Video element to display them.

When the video element is exited, the video continues to play in the background, sound audible. I’m looking for a way to pause or stop the video when the player is exited (hidden)

Thanks in advance!


Here is my site Read-Only: Webflow - Fawcett.Work

Hey Olly, cool site!

Looking at your page, you are using Webflow’s native video player, and you are showing/hiding several of them using interactions for a kind of lightbox-effect. My guess is that you want this behavior for all of them. When video is playing, and the video overlay is closed, that video should be automatically paused.

All good.

Webflow’s video player uses Embedly, which uses Playerjs - so you can accomplish this by detecting the hide ( using a MutationObserver ), and then pause the videos using Playerjs.

Place this in your before-/body custom code area.
Here’s what it does;

  1. Inventories the Embedly videos on your page, and creates a set of Players to reference them
  2. Inventories the DIVs that will show/hide from your interaction. We know these are all immediate children of your player-wrapper DIV. On these overlays, we install a MutationObserver to detect when a hide happens.
  3. The MutationObserver function detects the hide, and uses playerjs to pause it.

IMPORTANT: This is working great on your site with Vimeo vids. My guess in Youtube, etc. would also work as long as you’re using the Webflow native video control, you’ll probably get the Embedly playerjs setup.

<script src="https://cdn.embed.ly/player-0.0.11.min.js"></script>

<script>
  $(document).ready(function() {
    // Selecting the iframes by class and creating players for each
    var players = [];
    $('.player-wrapper .embedly-embed').each(function(index, elem) {
      players[index] = new playerjs.Player(elem);
    });

    // Create a MutationObserver instance
    var observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        if (mutation.attributeName === 'style') {
          var displayStyle = $(mutation.target).css('display');
          if (displayStyle === 'none') {
            // Find the index of the hidden div
            var index = $(mutation.target).index();
            // Pause the corresponding video
            players[index].pause();
          }
        }
      });
    });

    // Observe each child div for changes in its 'style' attribute
    $('.player-wrapper').children().each(function(index, elem) {
      observer.observe(elem, {
        attributes: true
      });
    });
  });
</script>

EDIT: Adding this here for later, since I might expand on this approach for a more generic solution.

Hi, thank you for the code, I managed to make it work on my site.

But what code in addition do I use when I would like to reset the videos to frame 0 when hidden?

My problem is that when I play (for example) video 1, then switch to video 2 and play it, and then go back to video 1, the player is not visible because the video is only paused on the frame I left it, but not stopped and reset. So users maybe don’t get it that they have to click or hover on the paused video again to play it.

I would prefer the videos to be reset once they’re hidden.

I would be very happy if someone could help me :slight_smile:

Hi Charlotte,

It’s difficult to imagine your UX setup here. “Hidden” usually refers to situations where the video container is actually hidden, e.g. a lightbox, popup, or videos that are in a tab, slider or accordion. You should still see the trigger that opened the video originally.

If you’re trying to do something different, this might not be the right approach for your situation. I generally need build these custom for each client because the code to detect the hidden state change depends entirely on the UX design.

However if everything’s working as you want and you just need to reset the video to the start, you can try something like this.

player.currentTime = 0; // Reset the video
player.pause(); // Stop the video

Hello, how would this work if the video is nested in several divs?

There is no difference.