jquerycolorbox

Stop HTML5 video playing in a Colorbox modal when the modal is closed


As many have written about before, when a modal containing a video is closed, the video keeps playing in the background. I need to stop or pause the video.

I've been looking through all the recommend script answers. None of them seem to reference Colorbox and its unique modal setup. It's not like Bootstrap, which is where most of the answers are. Colorbox's modal is wrapped by a div with embedded style, not a div with a class that can be easily use in a script:

<div style='display:none'>

I checked Colorbox FAQ and there's no mention of this problem.

Many of the solutions involve causing the video to pause when the close button is clicked. That could work, except the modal can also be exited by hitting the escape key or clicking anywhere outside the modal. The user can also click an arrow button to load the next modal directly, without explicitly closing the first modal. The video should also stop then. Some other solutions offered are for iframes, which this is not. It's HTML5 video.

Here's a sample of one of many videos on the page. Some of you Eagle Eyes will recognize Drupal markup in the class names. This is a Drupal site that is using Colorbox and Masonry libraries to make a gallery.

<div style='display:none'>
  <div id="inline-3642" class="colorbox-content flex">
    <div class="field field--name-field-gallery-item-title field--type-string field--label-hidden field--item">Test video</div>
    <video controls>
      <source src="/sites/default/files/FINAL_YouthCreate_2AugustaCAREs.mov" type="video/mp4">
    </video>
    <div class="field field--name-field-gallery-item-remote-video field--type-file field--label-hidden field--items">
      <div class="field--item">
        <span class="file file--mime-video-quicktime file--video icon-before"><span class="file-icon"><span class="icon glyphicon glyphicon-film text-primary" aria-hidden="true"></span></span><span class="file-link"><a href="https://opa-website.ddev.site/sites/default/files/FINAL_YouthCreate_2AugustaCAREs.mov" type="video/quicktime; length=47219945" title="Open video in new window" target="_blank" data-toggle="tooltip" data-placement="bottom">FINAL_YouthCreate_2AugustaCAREs.mov</a></span><span class="file-size">45.03 MB</span></span>
      </div>
    </div>
  </div>
</div>

Here is the code for the thumbnail I click on to launch the modal:

<div class="paragraph paragraph--type--masonry-gallery-item paragraph--view-mode--default">
  <a class="inline" href="#inline-3642">
    <div class="field field--name-field-gallery-item-thumbnail field--type-image field--label-hidden field--item">
      <img loading="lazy" src="/sites/default/files/2022-11/thumbnail-movie.png" width="2554" height="1298" alt="movie" typeof="foaf:Image" class="img-responsive" />
    </div>
  </a>
</div>

The buttons for going previous/next use the same IDs on all videos:

<button type="button" id="cboxNext" style="">next</button>
<button type="button" id="cboxPrevious" style="">previous</button>

Below in the comments, someone mentioned the initialization of the script.

Drupal.behaviors.colorboxInit = {
    attach: function () {
      $('.lightbox').click(function(e){
        e.preventDefault();
      });

      $('.lightbox').colorbox({
        rel: 'lightbox',
        transition:'none',
        width: '80%',
        height: '80%'
      });

      $('.inline').colorbox({
        inline:true,
        rel: 'lightbox',
        width: '80%'
      });
    }
  };

The videos are initialized with the .inline class.

I'd be grateful if anyone is able to point me in the right direction.


Solution

  • Appending an onClosed callback to the colorbox initialization will handle pausing of all video elements when the colorbox is closed.

    Adding a new custom click function on the colorbox's cboxPrev and cboxNext elements to pause all video elements will pause all videos when switching between slides.

    Drupal.behaviors.colorboxInit = {
    attach: function () {
      $('.lightbox').click(function (e) {
        e.preventDefault();
      });
    
      $('.lightbox').colorbox({
        rel: 'lightbox',
        transition: 'none',
        width: '80%',
        height: '80%'
      });
    
      $('.inline').colorbox({
        inline: true,
        rel: 'lightbox',
        width: '80%',
        onClosed: function () {
          $('video').each(function () {
            //pause the videos when modal is closed
            $(this).get(0).pause();
          });
        }
      });
    
      jQuery('body').on('click', '#cboxPrevious, #cboxNext', function () {
        jQuery('video').each(function () {
          //pause the videos when next and previouse arrows are used
          jQuery(this).get(0).pause();
        });
      });
    }};
    

    *Note that this will pause ALL video elements on the page. Ideally there would be some classes on these video elements to differentiate them.