angularserver-side-renderingswiper.jsangular17angular-ssr

How to handle Swiper 11 Web component events in Angular 17 SSR


I have this code working perfectly fine but I want to start using Swiper Webcomponent. How do I migrate this code to Swiper Webcomponent, specially, how to handle the events,

Here, I have slideChangeTransitionStart, slideChangeTransitionEnd event. On slideChangeTransitionEnd event, I need to call a method called setupImageZoom

HTML

<div class="swiper-container-wrapper">
  <div class="swiper-container swiper">
      <div class="swiper-wrapper">
        <div *ngFor="let slide of slides" class="swiper-slide">
          <div class="swiper-zoom-container"><img style="width: 100%;" [src]="slide.image"></div>
        </div>
      </div>
      <div class="swiper-pagination"></div>
      <div class="swiper-button-prev"></div>
      <div class="swiper-button-next"></div>
  </div>
  <div class="swiper-container thumbs-swiper thumbs-hover">
    <div class="swiper-wrapper">
      <div *ngFor="let slide of slides" class="swiper-slide">
        <div class="swiper-zoom-container"><img style="width: 100%;" [src]="slide.image"></div>
      </div>
    </div>
  </div>
</div>

TS

slides = [
    {image: '../../../../../assets/images/swiper-nature/nature-1.jpg'},
    {image: '../../../../../assets/images/swiper-nature/nature-2.jpg'},
    {image: '../../../../../assets/images/swiper-nature/nature-3.jpg'},
    {image: '../../../../../assets/images/swiper-nature/nature-4.jpg'},
    {image: '../../../../../assets/images/swiper-nature/nature-5.jpg'},
    {image: '../../../../../assets/images/swiper-nature/nature-6.jpg'},
    {image: '../../../../../assets/images/swiper-nature/nature-7.jpg'},
    {image: '../../../../../assets/images/swiper-nature/nature-8.jpg'},
    {image: '../../../../../assets/images/swiper-nature/nature-10.jpg'}
  ];

  ngAfterViewInit() {
    const thumbsSwiper = new Swiper(".thumbs-swiper", {
      loop: false,
      direction: 'vertical',
      spaceBetween: 10,
      slidesPerView: 6,
      watchSlidesProgress: true,
      centeredSlides: true,
      centeredSlidesBounds: true,
      watchOverflow: true,
      watchSlidesVisibility: true,
    });
    const mainSwiper = new Swiper('.swiper', {
      direction: 'horizontal',
      loop: false,
      speed: 400,
      spaceBetween: 100,
      mousewheel: {
        invert: true,
      },
      grabCursor: true,
      effect: 'creative',
      creativeEffect: {
        prev: {
          translate: [0, 0, -400],
        },
        next: {
          translate: ['100%', 0, 0],
        },
      },
      pagination: {
        el: '.swiper-pagination'
      },
      navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
      },
      zoom: {
        maxRatio: 10,
      },
      thumbs: {
        swiper: thumbsSwiper
      } 
    });
    mainSwiper.on("slideChangeTransitionStart",  () => {
      console.log('slideChangeTransitionStart');
      thumbsSwiper.slideTo(mainSwiper.activeIndex);
    });
    mainSwiper.on("slideChangeTransitionEnd", () => {
      console.log('mainSwiper slideChangeTransitionEnd');
      thumbsSwiper.slideTo(mainSwiper.activeIndex);
      this.setupImageZoom();
    });

    thumbsSwiper.on("slideChangeTransitionEnd", () => {
      console.log('thumbsSwiper slideChangeTransitionEnd');
      mainSwiper.slideTo(thumbsSwiper.activeIndex);
    });

  this.setupImageZoom();
  }

Solution

  • As per the documentation on Swiper Elements, we can just add the prefix swiper to the events, so

    All Swiper events are available as native DOM events but with lowercase names and swiper prefix (configurable via events-prefix parameter). E.g. slideChange becomes swiperslidechange.

    html

    <swiper-container
      slides-per-view="1"
      speed="500"
      loop="true"
      navigation="true"
      pagination="true"
      #swiper
      scrollbar="true"
      (swiperslidechangetransitionend)="setupImageZoom()"
    >
      <swiper-slide><img src="https://placehold.co/600x400" /></swiper-slide>
      <swiper-slide><img src="https://placehold.co/600x400" /></swiper-slide>
      <swiper-slide><img src="https://placehold.co/600x400" /></swiper-slide>
      <swiper-slide><img src="https://placehold.co/600x400" /></swiper-slide>
      <swiper-slide><img src="https://placehold.co/600x400" /></swiper-slide>
      <swiper-slide><img src="https://placehold.co/600x400" /></swiper-slide>
      <swiper-slide><img src="https://placehold.co/600x400" /></swiper-slide>
      <swiper-slide><img src="https://placehold.co/600x400" /></swiper-slide>
    </swiper-container>
    

    ts

    import { Component, OnInit, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
    
    @Component({
      selector: 'app-swiper',
      standalone: true,
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
      templateUrl: './swiper.component.html',
    })
    export class SwiperComponent implements OnInit {
      constructor() {}
    
      ngOnInit() {}
    
      ngAfterViewInit() {}
    
      setupImageZoom() {
        alert('setting up zoom!');
      }
    }
    

    Stackblitz Demo