Blieque
Blieque

Reputation: 675

Using Lightbox2 to display video

Site: http://blieque.comli.com/motion

Before I start, I know there are many alternatives to Lightbox2 (Lokesh Dhakar's) to display videos but I want to avoid using three different JavaScript things, already using MooTools and JQuery as I'd like to keep HTTP requests to a minimum, as well as disk usage.

As it comes, Lightbox2 does not support videos, full stop. However, I noticed that the JavaScript was essentially taking the contents of an a's href attribute and placing it in an img's src attribute when the light-box was open. As far as I can see, changing this img to an iframe (done) and setting the anchor tag's href to youtube.com/embed/*video-id* should generate an iframe containing that YouTube video (replacing watch?id= with embed/ presents a full screen version of the video.

I then also added JavaScript for width, height and frameborder attributes on top of the default class="lb-image". Now when the page is loaded and the Lightbox called it creates an empty window. If you inspect the code you can see all the attributes are there but the page in the frame frame isn't loaded, just creating an empty head and body tag.

I was just wondering if it was a server problem or a code problem and if so, how to fix it. If there any way to make it work?

Thanks

Note: I'm NOT using Drupal so the lightvideo option is not available.

Upvotes: 3

Views: 10364

Answers (1)

Patryk Niewiada
Patryk Niewiada

Reputation: 37

Maybe someone still is looking for solution.

I had same problem in my project. Not with youtube iframe but it’s not difficult to implenet it. Lightbox2 cannot be extended so i wrote simple class whose adding listener and observer. For proper displaing require is that video have a poster with the same sizes. That’s the fastest way to keep corret sizes of popup.

In href required is to add dataset href with image url

<a href="POSTER_URL" data-href="VIDEO_URL" data-lightbox="Videos">
Open Lightbox
</a>

SCSS to cover image in popup and set fade effect while loading

.lightbox {
  .lb {
    &-outerContainer {
      video {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        z-index: 9999;
        width: 100%;
        height: auto;
        opacity: 1;
        transition: opacity 300ms ease-in-out;
        border: none;
        outline: none;
        &:hover, &:focus {
          border: none;
          outline: none;
        }
      }
      &.animating {
        video {
          opacity: 0;
        }
      }
    }
    &-container {
      position: relative;
      .lb-image {
        border: none;
      }
    }
  }
}

And JS class which one create and set video into popup. Maybe little messy but i don't care. It's only quick solution.

class LightBoxVideo {
    constructor() {
        this.videos = {};
        this.lightBoxVideo();
    }

    lightBoxVideo = () => {
        this.setEvents();
        this.setMutationObserver();
    }

    setMutationObserver = () => {
        const observer = new MutationObserver(mutation => {
            const imageMutations = mutation.filter((m) => {
                return m.attributeName === "src" && m.target.className === 'lb-image'
            });
            
            const overlayDisplay = window.getComputedStyle(document.querySelector('.lightboxOverlay'), null).display;
            if("none" === overlayDisplay) {
                this.removeVideoElement();
            }
            
            if(imageMutations.length > 0) {
                if(this.videos[imageMutations[0].target.src]) {
                    this.removeVideoElement();
                    this.setVideoElement(this.videos[imageMutations[0].target.src]);
                }
            }
        });

        observer.observe(document.body, {
            childList: false,
            attributes: true,
            subtree: true,
            characterData: false
        });
    }

    setEvents = () => {
        const videoLinks = this.findVideoLinks();
        videoLinks.forEach((link) => {
            this.videos[link.href] = link;
            link.addEventListener('click', (e) => {
                this.removeVideoElement();
                this.setVideoElement(e.target);
            });
        });
    }

    setVideoElement = (element) => {
        const lightbox = document.querySelector('.lightbox')
        const container = lightbox.querySelector('.lb-container');

        const videoElement = this.createVideoElement(element);
        container.prepend(videoElement);
    }

    removeVideoElement = () => {
        const lightbox = document.querySelector('.lightbox')
        const container = lightbox.querySelector('.lb-container');
        const video = container.querySelector('video');

        if(video) {
            container.removeChild(video);
        }
    }

    createVideoElement = (element) => {
        const video = document.createElement('video');

        video.setAttribute('poster', element.href);
        video.setAttribute('controls', 'true');

        const source = document.createElement('source');
        source.setAttribute('src', element.dataset.href);
        source.setAttribute('type', 'video/mp4');

        video.append(source);

        return video;
    }

    findVideoLinks = () => {
        const hrefs = document.querySelectorAll('a[data-lightbox]');
        const regex = /\.(mp4|mov|flv|wmv)$/;
        if(0 === hrefs.length) {
            return [];
        }
        return Array.from(hrefs).filter((href) => {
            return !! href.dataset.href.match(regex);
        });
    }
}

To preview how it's work - codepen here: https://codepen.io/PatrykN/pen/RwKpwMe

Upvotes: 1

Related Questions