skip to Main Content

I found a lightweight lightbox code example, however, it relies on IDs and I intend to use it on 20+ items, I’d rather not have 20 hard-coded js lines to refer to something I know can be dynamic, I’m just not skilled enough with JS to condense into something clean.

codepen

HTML:

<template id="one">
    <h1>HTML &lt;template one&gt; Tag</h1>
    <p>The template element holds HTML code without displaying it.<br>Doesn't work in older browsers.</p>
</template>


<button class="template" data-ref="one">template</button>


<template id="two">
    <h1>HTML &lt;template two&gt; Tag</h1>
    <p>The template element holds HTML code without displaying it.<br>Doesn't work in older browsers.</p>
</template>


<button class="template" data-ref="two">template two</button>

JS:

const templateInstance = basicLightbox.create(document.querySelector('#one'))
const templateInstanceTwo = basicLightbox.create(document.querySelector('#two'))


document.querySelector('button.template' + '[data-ref=one]').onclick = templateInstance.show
document.querySelector('button.template' + '[data-ref=two]').onclick = templateInstanceTwo.show

Technically this works, but is repetitive and not scalable to large n templates.

2

Answers


  1. To DRY the logic up you can use a loop to iterate through all button.template elements to attach individual event handlers to them. In those event handlers you can read the value from the data-ref attribute and use it to instantiate the lightbox. Here’s a working example:

    document.querySelectorAll('button.template').forEach(button => {
      button.addEventListener('click', e => {    
        basicLightbox.create(document.querySelector(e.target.dataset.ref)).show();
      });
    });
    html {
      width: 100%;
      height: 100%;
      font-family: sans-serif;
    }
    
    body {
      display: flex;
      align-items: center;
      align-content: center;
      justify-content: center;
      flex-wrap: wrap;
      min-height: 100%;
      margin: 0;
      color: white;
      text-align: center;
    }
    
    button {
      display: inline-block;
      appearance: none;
      background: #2875ed;
      margin: .5em;
      padding: .5em 1em;
      border: none;
      color: white;
      font: inherit;
      border-radius: 3px;
      cursor: pointer;
      outline: none;
    }
    <link rel="stylesheet" href="//s.electerious.com/basicLightbox/dist/basicLightbox.min.css" />
    <script src="//s.electerious.com/basicLightbox/dist/basicLightbox.min.js"></script>
    <template id="one">
      <h1>HTML &lt;template one&gt; Tag</h1>
      <p>The template element holds HTML code without displaying it.<br>Doesn't work in older browsers.</p>
    </template>
    <button class="template" data-ref="#one">template</button>
    
    <template id="two">
      <h1>HTML &lt;template two&gt; Tag</h1>
      <p>The template element holds HTML code without displaying it.<br>Doesn't work in older browsers.</p>
    </template>
    <button class="template" data-ref="#two">template two</button>
    Login or Signup to reply.
  2. This is another way with plain javascript, no need for a external library:

    function init() {
        let buttons = document.querySelectorAll("button.template");
        for (let button of buttons) {
            button.onclick = showTemplate;
        }
    }
    
    function showTemplate(event) {
        let main = document.querySelector("main");
        let template = document.querySelector("template").content;
    
        let element = template.querySelector(`div#${event.currentTarget.dataset.templateId}`);
        if (!element) return;
    
        template.append(...main.childNodes);
        main.appendChild(element);
    }
    
    window.onload = init;
    * {
        font-family: Verdana, Geneva, Tahoma, sans-serif;
    }
    
    body {
        padding: 1rem;
    }
    
    button {
        font-size: 1rem;
        color: white;
        background-color: blue;
        border: none;
        border-radius: .25rem;
        padding: .50rem;
    }
    <nav>
        <button class="template" data-template-id="t1">Template 1</button>
        <button class="template" data-template-id="t2">Template 2</button>
        <button class="template" data-template-id="t3">Template 3</button>
        <button class="template" data-template-id="t4">Template 4</button>
    </nav>
    <br>
    <main>
        <h2>Select a template</h2>
    </main>
    
    <template>
        <div id="t1">
            <h1>Template 1</h1>
            <p>The day had begun on a bright note. The sun finally peeked through the rain for the first time in a week, and the birds were singing in its warmth. There was no way to anticipate what was about to happen. It was a worst-case scenario and there was no way out of it.</p>
        </div>
        <div id="t2">
            <h1>Template 2</h1>
            <p>It had been her dream for years but Dana had failed to take any action toward making it come true. There had always been a good excuse to delay or prioritize another project. As she woke, she realized she was once again at a crossroads. Would it be another excuse or would she finally find the courage to pursue her dream? Dana rose and took her first step.</p>
        </div>
        <div id="t3">
            <h1>Template 3</h1>
            <p>Breastfeeding is good for babies and moms. Infants that are breastfed get antibodies from their mothers against common illnesses. Breastfed babies have less chance of being obese as an adult. Breastfeeding a baby lets the infant-mother pair bond in a very unique way. Mother’s who breastfeed lower their chances of developing breast cancer. Usually, mothers who breastfeed lose their pregnancy weight more quickly and easily. The benefits of breastfeeding are numerous.</p>
        </div>
        <div id="t4">
            <h1>Template 4</h1>
            <p>The amber droplet hung from the branch, reaching fullness and ready to drop. It waited. While many of the other droplets were satisfied to form as big as they could and release, this droplet had other plans. It wanted to be part of history. It wanted to be remembered long after all the other droplets had dissolved into history. So it waited for the perfect specimen to fly by to trap and capture that it hoped would eventually be discovered hundreds of years in the future.</p>
        </div>
    </template>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search