Glide: Infinite Carousel cloned element lose eventlisteners.(example video included)

Created on 12 Dec 2018  路  14Comments  路  Source: glidejs/glide

Please see my recording Video
Infinite Carousel cloned element lose event listeners.
My workaround is not using carouse but slider. Which is ok by me.
I use Glide along with react. Maybe I did something wrong?
The code is nasty, I'm not going to put it here, feel free to close my issue.
But Glide is the only best carousel currently in modern JS world.
Other react carousel option has too many bugs. I've tried.

Most helpful comment

Not sure how it would be implemented in React, but I advise you to try with events delegation. In simple words add the event to a parent element, so it will not disappear after cloning and conditionally run login if the target is a desired element

function clickHandler(e) {
  if (e.target.matches('.item')) {
    console.log(e.target.innerHTML);
  }
}

const el = document.querySelector('.el');

el.addEventListener('click', clickHandler);

All 14 comments

I'm facing this issue recently as well where I defined a Vue click handler to go to the selected slide, but any of the clones getting clicked doesn't register an event. I would use the 'slider' option, but I don't like seeing blank spots at the end of the list. Any work arounds for this is appreciated. Thanks for GlideJS, btw!

I am also experiencing this issue with Vue. Did anyone figure out some clean workaround?

Is this custom infinite functionality or am I missing an option to enable this?

I'm also blocked on this with React Components as slide elements. The issue seems to be that append is simply cloning HTML elements so components/event listening on those elements don't work. Not sure that there's a simple workaround. The only thing I can think of is to overwrite the append method but I haven't tested if it's possible.

@Jorenm I think what you're looking for is type: 'carousel' in the Glide options.

@jedrzejchalubek Do you have any recommendations here? Thanks for your work on this!

Try putting your event listeners in the mount.after event.

I was having the same issue where my lightbox wasn't initiating on any cloned elements, but after putting my fancybox initialization in that mount.after event, I was able to get it to work.

$(function() {
  const glide = new Glide('.glide', {
    type: 'carousel',
    perView: 2,
    gap: 20,
    peek: { before: 0, after: 200 }
  });

  glide.on('mount.after', function() {
    $('[data-fancybox]').fancybox({
      buttons: [
        'zoom',
        'slideShow',
        'thumbs',
        'close'
      ]
    });
  });

  glide.mount();
});

Does not work with vanilla JS, cloned element lose click event.

glide.on(['mount.after'], function() { ... var ind = parseInt(target.getAttribute('data-index')) glide.go('='+ind) ; ... }); glide.mount();

Mounting carousel in a useEffect hook in react, cloned elements do not have any onClick functionality (original element works fine) any ideas?

Thanks

so, how to resolve this problem?

Not sure how it would be implemented in React, but I advise you to try with events delegation. In simple words add the event to a parent element, so it will not disappear after cloning and conditionally run login if the target is a desired element

function clickHandler(e) {
  if (e.target.matches('.item')) {
    console.log(e.target.innerHTML);
  }
}

const el = document.querySelector('.el');

el.addEventListener('click', clickHandler);

@jedrzejchalubek, in your code, which one is the parent and which is the child? Also, could you target child elements that are removed from parent by several levels? Thanks!

@mgalkus Events go up, through the DOM, so add the event listener to the glide track or something (something that won't be removed) and then you can get the event's target to work out which slide the event was targeted at. Great idea @jedrzejchalubek :)

I have the same problem in Vue, when cloned slide not load some props inside.
<vue-glade-slide>
<component :props='data'>
</vue-glade-slide>

Also had issues here in a React/Gatsby app. Went with the click handler solve above, just targeting the clones only. Not great but it worked.

Not sure how it would be implemented in React, but I advise you to try with events delegation. In simple words add the event to a parent element, so it will not disappear after cloning and conditionally run login if the target is a desired element

function clickHandler(e) {
  if (e.target.matches('.item')) {
    console.log(e.target.innerHTML);
  }
}

const el = document.querySelector('.el');

el.addEventListener('click', clickHandler);

This is a big offtopic but this solved my case:

glide.on('mount.after', function() {
    GLightbox({selector: '[data-lightbox]'});
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

adambartosiewicz picture adambartosiewicz  路  3Comments

philmarc picture philmarc  路  3Comments

dodozhang21 picture dodozhang21  路  5Comments

garygreen picture garygreen  路  3Comments

thasmo picture thasmo  路  4Comments