leo6104 / ngx-slick-carousel

Angular 17+ wrapper for slick plugin
107 stars 43 forks source link

Angular click event not fired on slick-cloned element #31

Open steosoft opened 5 years ago

steosoft commented 5 years ago

When using infinite slick carousel some of the elements are being cloned to allow infinite scrolling. Cloned elements has class "slick-cloned" beside standard classes "slide slick-slide".

If I attach Angular (click) event to slick item (or image inside slick item), events are not fired on elements marked as "slick-cloned".

Can you fix that or help what should I do to make it work?

Below my example code: .html file:

<ngx-slick-carousel class="carousel" #slickModal="slick-carousel" [config]="slideConfig">
  <div ngxSlickItem *ngFor="let slide of slides" class="slide" (click)="clicked(slide.img)">
    <img src="{{ slide.img }}" alt="" width="100%">
  </div>
</ngx-slick-carousel>

.ts file:

  slides = [
    {img: "http://placehold.it/350x150/000000"},
    {img: "http://placehold.it/350x150/111111"},
    {img: "http://placehold.it/350x150/333333"},
    {img: "http://placehold.it/350x150/222222"},
    {img: "http://placehold.it/350x150/999999"},
    {img: "http://placehold.it/350x150/444444"},
    {img: "http://placehold.it/350x150/888888"},
    {img: "http://placehold.it/350x150/777777"}
  ];
  slideConfig = {"slidesToShow": 4, "slidesToScroll": 1};

  clicked(img) {
    console.log("clicked img " + img);
  }
anelad commented 5 years ago

+1

anelad commented 5 years ago

I've created this workaround:

  afterChange(e) {
    const elements = e.event.target.lastChild.firstChild.getElementsByClassName('slick-cloned');
    for (const element of elements) {
     element.addEventListener('click', this.itemSelectionFunction.bind(this));
    }
  }

Do not forget to register your slider for afterChange events.

leo6104 commented 5 years ago

https://github.com/leo6104/ngx-slick-carousel/issues/18 Same issue.

dami95 commented 4 years ago

+1

orabs commented 4 years ago

Can someone help and add full solution for this issue , I spend so many hours in trying to solve it !! Please any one ?? (If you can dont send a link for another issue in this repository , All the issues here didnt realy helped)

SlimenTN commented 4 years ago

any update about this issue ?

lookMyCode commented 3 years ago

HTML:
` <ngx-slick-carousel class="carousel logos_slider"

slickModal="slick-carousel"

                    [config]="slideConfig" 
                    (init)="afterSliderChange()"
                    (afterChange)="afterSliderChange()" 
        >
<\img src="assets/images/ar.png" class="w-100"/>

`
image


TS:
afterSliderChange(e?: any) { const elems: NodeListOf<HTMLElement> = document.querySelectorAll('.logos_slider__btn'); let elements: HTMLElement[] = []; for (let k in elems) { elements.push(elems[k]); } elements = elements.filter(elem => typeof(elem) === 'object'); for (const element of elements) { if (element) { const shortcode: string = element.dataset.shortcode; element.onclick = this.logotypeSearch.bind(this, shortcode); } } }
image

kuldeepsingh99 commented 2 years ago

Can someone provide the whole code

kuldeepsingh99 commented 2 years ago

HTML: ` <ngx-slick-carousel class="carousel logos_slider" #slickModal="slick-carousel" [config]="slideConfig" (init)="afterSliderChange()" (afterChange)="afterSliderChange()" >

<\img src="assets/images/ar.png" class="w-100"/> ![image](https://user-images.githubusercontent.com/46138135/121884457-3ad45a00-cd13-11eb-811a-6fffaa0a9aca.png) TS:afterSliderChange(e?: any) { const elems: NodeListOf = document.querySelectorAll('.logos_slider__btn'); let elements: HTMLElement[] = []; for (let k in elems) { elements.push(elems[k]); } elements = elements.filter(elem => typeof(elem) === 'object'); for (const element of elements) { if (element) { const shortcode: string = element.dataset.shortcode; element.onclick = this.logotypeSearch.bind(this, shortcode); } } }` image

what is this variable logotypeSearch

lookMyCode commented 2 years ago

HTML: <ngx-slick-carousel class="carousel logos_slider" #slickModal="slick-carousel" [config]="slideConfig" (init)="afterSliderChange()" (afterChange)="afterSliderChange()" > <\img src="assets/images/ar.png" class="w-100"/> image TS:afterSliderChange(e?: any) { const elems: NodeListOf = document.querySelectorAll('.logos_slider__btn'); let elements: HTMLElement[] = []; for (let k in elems) { elements.push(elems[k]); } elements = elements.filter(elem => typeof(elem) === 'object'); for (const element of elements) { if (element) { const shortcode: string = element.dataset.shortcode; element.onclick = this.logotypeSearch.bind(this, shortcode); } } } image

what is this variable logotypeSearch

That is a method, it sends a short code to the backend and gets some result. The method does not affect the operation of the slider.

nishanc commented 9 months ago

This is what I use as a workaround.

afterChange(changeEvent: any) {
    const elements = changeEvent.event.target.lastElementChild.firstChild.getElementsByClassName('slick-cloned') as HTMLElement[];
    for (const element of elements) {
      if(!element.classList.contains('listen')){
        element.classList.add('listen')
        element.addEventListener('click', (clickEvent: any) => {
          // Navigation logic here
        });
      }
    }
  }

Add (afterChange) to template

<ngx-slick-carousel
      class="carousel"
      #slickModal="slick-carousel"
      (afterChange)="afterChange($event)"
      [config]="marqueeConfig"
>

Based on anelad's comment