Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite Carousel cloned element lose eventlisteners.(example video included) #302

Closed
rockmandash opened this issue Dec 12, 2018 · 16 comments

Comments

@rockmandash
Copy link

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.

@jeissler
Copy link

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!

@mikusd
Copy link

mikusd commented Jan 15, 2019

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

@Jorenm
Copy link

Jorenm commented Jan 17, 2019

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

@kanaabe
Copy link

kanaabe commented Jan 18, 2019

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!

@drewrawitz
Copy link

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();
});

@italo1983
Copy link

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();

@opr
Copy link

opr commented Oct 4, 2019

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

Thanks

@EthianWong
Copy link

so, how to resolve this problem?

@jedrzejchalubek
Copy link
Member

jedrzejchalubek commented Oct 9, 2019

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);

@mgalkus
Copy link

mgalkus commented Dec 21, 2019

@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!

@opr
Copy link

opr commented Dec 27, 2019

@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 :)

@Enigama
Copy link

Enigama commented May 22, 2020

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

@wade-wojcak
Copy link

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.

@npoggenburg
Copy link

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]'});
});

@Leapfrognz
Copy link

Also have this issue. cloned slides are not ioncluding the events handlers added via a vue app.

@jedrzejchalubek
Copy link
Member

jedrzejchalubek commented Nov 21, 2021

The cloned element will lose its event listeners and there is no way to pass it on cloning. The current implementation of infinity scrolling has this limitation. The solution here is to use event delegation that I described here: #302 (comment)

Changing this implementation logic so slides are not cloned but changes their positions is on my roadmap

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests