javascripthtmljquerycsslightgallery

How to append a dynamic element to an image opened in lightgallery.js


I have a page that show lots of photos which can be opened with lightgallery.js

I've already made some custom HTML caption which works fine. But now I want to add a label to the image itself. How can I do that?

I will show an example of what my photos page looks like:

enter image description here

When you open an image this is what it looks like:

enter image description here

The left part is a custom HTML caption which I linked with this attribute: data-sub-html.

Example code of my looped code:

$photomasonry .= '
<div class="tile scale-anm noselect">
  <a href="https://studio.website.nl/'.$getphotos['preview'].'" data-sub-html="#caption'.$imgcount.'" class="item masonrytile" data-src="https://studio.website.nl/'.$getphotos['preview'].'">
    <img src="https://studio.website.nl/'.$getphotos['preview'].'"/>
    <span class="idlabel">'.$getphotos['id'].'</span>
    <span class="sizelabel">'.$size.'</span>
  </a>
</div>';
$photomasonry .= '
<div id="caption'.$imgcount.'" style="display:none">
  <img src="https://studio.website.nl/images/logo.png">
  <h4 class="subhtmlh4">Maak iets moois met deze foto</h4>
  <div class="gallerypopupbtns">
    <a href="design-magazijn/stockfotos/'.$_GET['alias'].'/'.$getphotos['id'].'"><button class="btnstyle purplebtn" type="button" name="button">Maak iets moois</button></a>
  </div>
</div>';
$imgcount++;

But now I want this purple size icon (L, XL, XX) as a label on the image when lightgallery is opened. How can I do this? The html of the lightgallery is only generated after the page is loaded.

I want to add an element inside this part:

<div class="lg-img-wrap">
    <img class="lg-object lg-image" src="https://studio.website.nl/images/photos/previews/preview-bb58317c8d05e29b32963e7a295a5b9f.jpg">
</div>

But not just that, the content is dynamic, so display the correct size for the correct image. I already created this for the photo overview page but not when clicking a photo.


Solution

  • According to the lightgallery docs, you can use the event lgAfterOpen to execute code once the gallery is opened. However, lightgallery makes this slightly difficult as you can't access the image clicked on from this event, but you can access it from the event lgBeforeOpen. With this in mind, I'd accomplish this by doing two things.

    Firstly, add the size as a data attribute of each image:

    <img src="https://studio.website.nl/'.$getphotos['preview'].'" data-size="'.$size.'"/>
    

    Secondly, add the following functions when initialising lightgallery:

    // example gallery definition
    const lg = document.getElementById('custom-events-demo');
    // add the following functions
    lg.addEventListener('lgBeforeOpen', (event) => {
      //add datasize property to target so it can be accessed in the afterOpen function
      event.target.dataset.size = event.explicitOriginalTarget.dataset.size;
    });
    lg.addEventListener('lgAfterOpen', (event) => {
      // get size from data attribute
      var size = event.target.dataset.size;
      // get the .lg-img-wrap div to append size to
      var imgWrap = document.querySelector(".lg-container.lg-show .lg-img-wrap");
      // create and append span
      var sizeSpan = document.createElement("span");
      sizeSpan.classList.add("sizelabel");
      sizeSpan.innerHTML = size;
      imgWrap.appendChild(sizeSpan);
    });
    //initialise lightgallery
    lightGallery(lg);
    

    You may be using a different version of lightgallery, but when I tested this the .lg-img-wrap element was a picture element not a div, so I replaced the last line of the event listener function with the following to get the size to show:

    imgWrap.parentElement.appendChild(sizeSpan);
    

    You might need a bit of extra CSS to position the size span as you wish, but just to get it to show all you need is:

    .sizelabel {
      position: relative;
    }
    

    Note: I don't think this will work if you navigate to a different image from within lightgallery as it won't update the size, and in fact the size might just get removed. To fix this you'd probably need to do something using the lgAfterSlide event and the index of the image, but from your screenshot it looks like you don't expect the user to scroll through images within lightgallery anyway so this may not be an issue.