Search code examples
javascripthtmlowl-carousel

How to add dynamic elements in Owl Carousel?


I have a problem with Owl-carousel when I add dynamic data using vanilla JavaScript it rendered in side .owl-carousel but not working.

const moreProjects = [
{
 image: "./images/huddle-landing.jpg",
 title: "Huddle landing page",
 desc: "The challenge from frontend mentor, this helps me to practice my layout skills.",
 github:"https://github.com/hatwell-jonel/frontendmentor-huddle-landingpage.git",
 preview: "https://hatwell-jonel.github.io/frontendmentor-huddle-landingpage/",
},
{
 image: "./images/loopstudios-landing.jpg",
 title: "Loopstudios landing page",
 desc: "The challenge from frontend mentor, this helps me to practice my knowledge using CSS Grid.",
 github:"https://github.com/hatwell-jonel/frontendmentor-loopstudio.git",
preview: "https://hatwell-jonel.github.io/frontendmentor-loopstudio/",
},
{
 image: "./images/pricingcomponent.jpg",
 title: "Pricing component",
 desc: "The challenge from frontend mentor, this helps me to increase my knowledge on JavaScript and how to style input range.",
 github:"https://github.com/hatwell-jonel/frontendmentor-pricingcomponent.git",
 preview: "https://hatwell-jonel.github.io/frontendmentor-pricingcomponent/",
},
]

const carouselDOM = document.querySelector(".owl-carousel");

function moreProj(projects){
  let project = projects.map( (project) => {
  const {image, title,desc,github, preview} = project;
   return `
      <div class="card">
        <div class="card-img">
          <img src="${image}" class="img-fluuid" alt="project image">
        </div>
        <div class="card-content">
          <div class="indicator">
            <i class="fa-solid fa-grip-lines"></i>
          </div>
          <h3 class="title">${title}</h3>
          <p class="desc">${desc}</p>
          <div class="links">
            <a href="${github}" class="link" target="_blank">
              <i class="fa-brands fa-github"></i>
              Github
            </a>
            <a href="${preview}" class="link" target="_blank">
              <i class="fa-solid fa-eye"></i>
              Preview
            </a>
          </div>
        </div>
    </div>`;
  });
   project = project.join("");
   carouselDOM.innerHTML = project;
 }

 moreProj(moreProjects);

I need it to render here:

 <section class="carousel">
    <div class="owl-carousel owl-theme">
        <!-- RENDER ELEMENTS HERE -->
    </div>
  </section>

is there a way to solve this problem? Thank you for your time.

This is the output of the code. my output

this is my desired output. desired output


Solution

  • 2 Changes I would like to mention in your code :

    • Use ID selector instead of class selector to find DOM node.
    • Update the DOM only once. Changing the innerHTML inside the map is not efficient as you are triggering multiple reflow. We can do it in only one reflow by updating the innerHTML after the map. Reflow operation uses CPU and is more expensive than repaint operation. This might be an issue if the projects array is very large.

    function moreProj(projects) {
      let project = projects.map((project) => {
        const {
          image,
          title,
          desc,
          github,
          preview
        } = project;
        return `
          <div class="card">
            <div class="card-img">
              <img src="${image}" class="img-fluuid" alt="project image">
            </div>
            <div class="card-content">
              <div class="indicator">
                <i class="fa-solid fa-grip-lines"></i>
              </div>
              <h3 class="title">${title}</h3>
              <p class="desc">${desc}</p>
              <div class="links">
                <a href="${github}" class="link" target="_blank">
                  <i class="fa-brands fa-github"></i>
                  Github
                </a>
                <a href="${preview}" class="link" target="_blank">
                  <i class="fa-solid fa-eye"></i>
                  Preview
                </a>
              </div>
            </div>
        </div>
    `;
    
      });
    
      return project;
    }
    
    const moreProjects = [{
        image: "./images/huddle-landing.jpg",
        title: "Huddle landing page",
        desc: "The challenge from frontend mentor, this helps me to practice my layout skills.",
        github: "https://github.com/hatwell-jonel/frontendmentor-huddle-landingpage.git",
        preview: "https://hatwell-jonel.github.io/frontendmentor-huddle-landingpage/",
      },
      {
        image: "./images/loopstudios-landing.jpg",
        title: "Loopstudios landing page",
        desc: "The challenge from frontend mentor, this helps me to practice my knowledge using CSS Grid.",
        github: "https://github.com/hatwell-jonel/frontendmentor-loopstudio.git",
        preview: "https://hatwell-jonel.github.io/frontendmentor-loopstudio/",
      },
      {
        image: "./images/pricingcomponent.jpg",
        title: "Pricing component",
        desc: "The challenge from frontend mentor, this helps me to increase my knowledge on JavaScript and how to style input range.",
        github: "https://github.com/hatwell-jonel/frontendmentor-pricingcomponent.git",
        preview: "https://hatwell-jonel.github.io/frontendmentor-pricingcomponent/",
      },
    ];
    
    const carouselDOM = document.querySelector("#owl-carousel");
    const projects = moreProj(moreProjects);
    let template = "";
    
    for (const project of projects) {
      template += project;
    }
    
    // Updating the DOM only once after all projects are processed
    carouselDOM.innerHTML = template;
    <section class="carousel">
      <div id="owl-carousel" class="owl-carousel owl-theme">
        <!-- RENDER ELEMENTS HERE -->
      </div>
    </section>