banthagroup / fslightbox

An easy to use vanilla JavaScript plug-in without production dependencies for displaying images, videos, or, through custom sources, anything you want in a clean overlying box.
MIT License
351 stars 30 forks source link

refreshFsLightbox not working on shadow DOM / web component #176

Open DaVince opened 3 years ago

DaVince commented 3 years ago

I'm using HTML's templating functionality to create a custom image-gallery component. However, running refreshFsLightbox() after instantiating a component seems to have no effect: the newly created components do not get a click event listener attached to them.

HTML:

<template id="gallery-item">
  <figure class="gallery-item">
    <a data-fslightbox="gallery" href="res/placeholder.png">
      <img width="150" height="150" src="res/thumb/placeholder.png" alt="" loading="eager">
    </a>
    <figcaption>Caption</figcaption>
  </figure>
</template>
<image-gallery id="spheredev">
  <gallery-item data-caption="hello">spherical-website.png</gallery-item>
  <gallery-item>spherical-website.png</gallery-item>
  <gallery-item>spherical-website.png</gallery-item>
</image-gallery>

JS:

class ImageGallery extends HTMLElement {
  constructor() {
    super();
    let shadowRoot = this.attachShadow({ mode: 'open' });
    const galleryItemTemplate = document.getElementById("gallery-item");
    const galleryItems = Array.from(this.children);

    // Add each gallery item
    galleryItems.forEach(item => {
      const elem = galleryItemTemplate.content.cloneNode(true);
      const link = elem.querySelector("a");
      const img = elem.querySelector("img");
      link.setAttribute("data-fslightbox", this.id ? this.id : "gallery");
      link.setAttribute("href", `res/${item.textContent}`);
      img.setAttribute("src", `res/thumb/${item.textContent}`);
      shadowRoot.append(elem);
    });
    refreshFsLightbox();  // Doesn't work on the above elements!
  }
}
window.customElements.define('image-gallery', ImageGallery);

I have confirmed that refreshFsLightbox() is invoked, it just skips anything that's inside of a shadow DOM.

(Side note: I'm still learning web components and probably doing some things in a roundabout way)