Search code examples
javascriptwistia

How to capture all videos in to be playable in video player script?


In the example below, I'm trying to capture all the videos in this script. However, I'm only able to capture the first video. I understand this has to do with getElementById and not querySelectorAll, but I'm not sure how to implement it in this script.

var videoId = document.getElementById("wistia_video");
var uniqueVideoId = Array.from(videoId.classList)
  .find((c) => c.startsWith("wistia_async_"))
  .substring(13);
// console.log(uniqueVideoId);

const clickToPlay = document.querySelectorAll('.wistia')[0];

clickToPlay.addEventListener('click', function() {
  const playVideo = clickToPlay.querySelectorAll('.wistia__overlay, .embed-youtube__play');
  Array.from(playVideo).forEach((elem) => elem.remove());

  //supporting scripts
  let wistiaSupportScripts = [
    `https://fast.wistia.com/assets/external/E-v1.js`,
    //adds jsonp file to provide security over requests
    `https://fast.wistia.com/embed/medias/${uniqueVideoId}.jsonp`
  ];

  //loads supporting scripts into head
  for (var i = 0; i < wistiaSupportScripts.length; i++) {
    let wistiaSupportScript = document.createElement("script");
    wistiaSupportScript.src = wistiaSupportScripts[i];
    let complete = false;
    if (!complete && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) {
      complete = true;
    }

    let wistiaContainers = document.querySelector(".wistia");

    wistiaContainers ? document.getElementsByTagName("head")[0].appendChild(wistiaSupportScript) : console.log("No Wistia videos here.");
  }

  window._wq = window._wq || [];
  _wq.push({
    //globally scoped
    id: uniqueVideoId,
    options: {
      autoPlay: true,
      volume: 0.5
    },

    onReady: function(video) {
      video.bind("play");
    }
  });
});
.wistia {
  position: relative;
  display: block;
  width: 100%;
  max-width: 500px;
  padding: 0;
  overflow: hidden;
  cursor: pointer;
}
.wistia__overlay {
  width: 100%;
  height: auto;
}
.wistia::before {
  display: block;
  content: "";
}
.wistia button.embed-youtube__play {
  background: url("https://nextiva.com/assets/svg/play-button.svg") no-repeat center center, rgba(33, 33, 33, 0.8);
  background-size: 40%;
  background-position: 55%;
  border: 0;
  border-radius: 50%;
  position: absolute;
  transition: all 0.2s ease;
  -webkit-transition: background 0.2s;
  width: 10%;
  aspect-ratio: 1/1;
  max-height: 15%;    
  cursor: pointer;
  z-index: 10;
  display: flex;
  justify-content: center;
  align-items: center;
  top: 50%;
  left: 50%;
  transform: translate3d(-50%, -50%, 0);
}
.wistia:hover button.embed-youtube__play,
.wistia button.embed-youtube__play:focus-visible,
.wistia button.embed-youtube__play:focus {
  background: url("https://nextiva.com/assets/svg/play-button.svg") no-repeat center center, #005fec;
  background-size: 40%;
  background-position: 55%;
}
.wistia_embed,
.wistia embed,
.wistia iframe {
  width: 100%;
  max-height: 100%;
}
<div class="wistia">
  <picture>
    <source srcset="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=640" media="(min-width: 1200px)">
    <source srcset="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=310" media="(min-width: 768px)">
    <img src="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=310" alt="some text" class="wistia__overlay lazy" loading="lazy">
  </picture>
  <div class="wistia_embed wistia_async_vhkqhqhzyq videoFoam=true" id="wistia_video"></div>
  <button class="embed-youtube__play"></button>
</div>

<div class="wistia">
  <picture>
    <source srcset="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=640" media="(min-width: 1200px)">
    <source srcset="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=310" media="(min-width: 768px)">
    <img src="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=310" alt="Some text" class="wistia__overlay lazy" loading="lazy">
  </picture>
  <div class="wistia_embed wistia_async_8ei13wuby7 videoFoam=true" id="wistia_video"></div>
  <button class="embed-youtube__play"></button>
</div>


Solution

  • You were only selecting the first .wistia block with this line:

    const clickToPlay = document.querySelectorAll('.wistia')[0];

    The other issue is the duplicated id as you noted, so that only the first video would be properly loaded. I have removed the id attribute entirely from the HTML, and updated the JS to properly loop over each .wistia div, attach a click handler, and then read the video ID from the associated child node.

    The gist of the changes are:

    // Loop over every .wistia node and attach a click handler to each
    Array.from(document.querySelectorAll(".wistia")).forEach(node => {
      node.addEventListener('click', () => {
        // Read the video ID from within the current .wistia blocks children
        const videoId = getVideoId(node)
    
        // The rest is mostly how you had it before
    
      })
    })
    

    const getVideoId = (ele) => {
      const classes = Array.from(ele.querySelector(".wistia_embed").classList);
      const idClass = classes.find((cls) => cls.startsWith("wistia_async_"));
      const id = idClass.replace("wistia_async_", "");
    
      return id;
    };
    const removeElems = (ele) => {
      const toRemove = Array.from(
    ele.querySelectorAll(".wistia__overlay, .embed-youtube__play")
      );
    
      toRemove.forEach((node) => node.remove());
    };
    
    Array.from(document.querySelectorAll(".wistia")).forEach((node) => {
      node.addEventListener("click", () => {
    const videoId = getVideoId(node);
    let wistiaSupportScripts = [
      `https://fast.wistia.com/assets/external/E-v1.js`,
      //adds jsonp file to provide security over requests
      `https://fast.wistia.com/embed/medias/${videoId}.jsonp`,
    ];
    
    removeElems(node);
    
    //loads supporting scripts into head
    for (var i = 0; i < wistiaSupportScripts.length; i++) {
      let wistiaSupportScript = document.createElement("script");
      wistiaSupportScript.src = wistiaSupportScripts[i];
      let complete = false;
      if (
        !complete &&
        (!this.readyState ||
          this.readyState == "loaded" ||
          this.readyState == "complete")
      ) {
        complete = true;
      }
    
      let wistiaContainers = document.querySelector(".wistia");
    
      wistiaContainers
        ? document
            .getElementsByTagName("head")[0]
            .appendChild(wistiaSupportScript)
        : console.log("No Wistia videos here.");
    }
    
    window._wq = window._wq || [];
    _wq.push({
      //globally scoped
      id: videoId,
      options: {
        autoPlay: true,
        volume: 0.5,
      },
    
      onReady: function (video) {
        video.bind("play");
      },
    });
      });
    });
    .wistia {
      position: relative;
      display: block;
      width: 100%;
      max-width: 500px;
      padding: 0;
      overflow: hidden;
      cursor: pointer;
    }
    .wistia__overlay {
      width: 100%;
      height: auto;
    }
    .wistia::before {
      display: block;
      content: "";
    }
    .wistia button.embed-youtube__play {
      background: url("https://nextiva.com/assets/svg/play-button.svg") no-repeat center center, rgba(33, 33, 33, 0.8);
      background-size: 40%;
      background-position: 55%;
      border: 0;
      border-radius: 50%;
      position: absolute;
      transition: all 0.2s ease;
      -webkit-transition: background 0.2s;
      width: 10%;
      aspect-ratio: 1/1;
      max-height: 15%;    
      cursor: pointer;
      z-index: 10;
      display: flex;
      justify-content: center;
      align-items: center;
      top: 50%;
      left: 50%;
      transform: translate3d(-50%, -50%, 0);
    }
    .wistia:hover button.embed-youtube__play,
    .wistia button.embed-youtube__play:focus-visible,
    .wistia button.embed-youtube__play:focus {
      background: url("https://nextiva.com/assets/svg/play-button.svg") no-repeat center center, #005fec;
      background-size: 40%;
      background-position: 55%;
    }
    .wistia_embed,
    .wistia embed,
    .wistia iframe {
      width: 100%;
      max-height: 100%;
    }
    <div class="wistia">
      <picture>
        <source srcset="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=640" media="(min-width: 1200px)">
        <source srcset="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=310" media="(min-width: 768px)">
        <img src="https://embedwistia-a.akamaihd.net/deliveries/48f1d62d1ceddb4284ad9cf67c916235.jpg?auto=format&w=310" alt="some text" class="wistia__overlay lazy" loading="lazy">
      </picture>
      <div class="wistia_embed wistia_async_vhkqhqhzyq videoFoam=true"></div>
      <button class="embed-youtube__play"></button>
    </div>
    
    <div class="wistia">
      <picture>
        <source srcset="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=640" media="(min-width: 1200px)">
        <source srcset="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=310" media="(min-width: 768px)">
        <img src="https://embed-fastly.wistia.com/deliveries/2eab84ad71cf5acd9c7572d36667d255.jpg?auto=format&w=310" alt="Some text" class="wistia__overlay lazy" loading="lazy">
      </picture>
      <div class="wistia_embed wistia_async_8ei13wuby7 videoFoam=true"></div>
      <button class="embed-youtube__play"></button>
    </div>