How might I be able to clean up this javascript a little bit?

Functions declared within loops referencing an outer scoped variable may lead to confusing semantics.

It’s in 2 spots in here.

How do I fix them?

https://jsfiddle.net/2gpu38sx/

(function() {
  let YouTubeContainers = document.querySelectorAll(".embed-youtube");

  // Iterate over every YouTube container you may have
  for (let i = 0; i < YouTubeContainers.length; i++) {
    let container = YouTubeContainers[i];
    let imageSource = "https://img.youtube.com/vi/" + container.dataset.videoId + "/sddefault.jpg";

    // Load the Thumbnail Image asynchronously
    let image = new Image();
    image.src = imageSource;
    image.addEventListener("load", function() {
      container.appendChild(image);
    });

    // When the user clicks on the container, load the embedded YouTube video
    container.querySelector("button").addEventListener("click", function() {
      let iframe = document.createElement("iframe");

      iframe.setAttribute("frameborder", "0");
      iframe.setAttribute("allowfullscreen", "");
      iframe.setAttribute("allow", "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture");
      // Important: add the autoplay GET parameter, otherwise the user would need to click over the YouTube video again to play it 
      iframe.setAttribute("src", "https://www.youtube.com/embed/" + container.dataset.videoId + "?rel=0&showinfo=0&autoplay=1&fs=0");

      // Clear Thumbnail and load the YouTube iframe
      container.innerHTML = "";
      container.appendChild(iframe);
    });
  }
})();

I think your code is quite normal, but just for interest I tried to use here event delegation…

(function () {
  let YouTubeContainers = document.querySelectorAll(".embed-youtube");
  const imagesMap = new Map();
  document.body.addEventListener(
    "load",
    function ({ target }) {
      if (imagesMap.has(target)) {
        target.style.display = "inline";
        imagesMap.get(target).append(target);
      }
    },
    true
  );
  // Iterate over every YouTube container you may have
  for (let i = 0; i < YouTubeContainers.length; i++) {
    let container = YouTubeContainers[i];
    let imageSource =
      "https://img.youtube.com/vi/" +
      container.dataset.videoId +
      "/sddefault.jpg";

    // Load the Thumbnail Image asynchronously
    let image = new Image();
    document.body.append(image);
    image.style.display = "none";
    image.src = imageSource;
    imagesMap.set(image, container);
  }
})();

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.