Skip to content

Latest commit

 

History

History
509 lines (356 loc) · 12.9 KB

File metadata and controls

509 lines (356 loc) · 12.9 KB
title description order date
Events
Learn how to listen to Embla Carousel events and how to make use of them.
2
2021-02-21

import { Tabs } from 'components/Tabs/Tabs' import { TabsItem } from 'components/Tabs/TabsItem' import { TABS_LIBRARY } from 'consts/tabs'

Events

Embla Carousel exposes events that you can listen to in order to react to changes in the carousel.


Usage

You need an initialized carousel in order to make use of events. Events will only be fired during the lifecycle of a carousel and added event listeners will persist even when you hard reset the carousel with the reInit method.

Adding event listeners

After initializing a carousel, we're going to subscribe to the slidesInView event in the following example:

import EmblaCarousel from 'embla-carousel'

const emblaNode = document.querySelector('.embla')
const emblaApi = EmblaCarousel(emblaNode)

function logSlidesInView(emblaApi) {
  console.log(emblaApi.slidesInView())
}

emblaApi.on('slidesInView', logSlidesInView)
import { useCallback, useEffect } from 'react'
import useEmblaCarousel from 'embla-carousel-react'

export function EmblaCarousel() {
  const [emblaRef, emblaApi] = useEmblaCarousel()

  const logSlidesInView = useCallback((emblaApi) => {
    console.log(emblaApi.slidesInView())
  }, [])

  useEffect(() => {
    if (emblaApi) emblaApi.on('slidesInView', logSlidesInView)
  }, [emblaApi, logSlidesInView])

  // ...
}
<script setup>
  import { onMounted } from 'vue'
  import emblaCarouselVue from 'embla-carousel-vue'

  const [emblaRef, emblaApi] = emblaCarouselVue()

  function logSlidesInView(emblaApi) {
    console.log(emblaApi.slidesInView())
  }

  onMounted(() => {
    if (emblaApi.value) emblaApi.value.on('slidesInView', logSlidesInView)
  })

  // ...
</script>
import { onMount } from 'solid-js'
import createEmblaCarousel from 'embla-carousel-solid'

export function EmblaCarousel() {
  const [emblaRef, emblaApi] = createEmblaCarousel()

  function logSlidesInView(emblaApi) {
    console.log(emblaApi.slidesInView())
  }

  onMount(() => {
    const api = emblaApi()
    if (api) api.on('slidesInView', logSlidesInView)
  })

  // ...
}
<script>
  import emblaCarouselSvelte from 'embla-carousel-svelte'

  let emblaApi

  function logSlidesInView(emblaApi) {
    console.log(emblaApi.slidesInView())
  }

  function onInit(event) {
    emblaApi = event.detail
    emblaApi.on('slidesInView', logSlidesInView)
  }
</script>

<div class="embla" use:emblaCarouselSvelte on:emblaInit="{onInit}">...</div>

Removing event listeners

In order to remove an event listener, you'll have to call the off method and make sure to pass the same callback reference you passed to the on method:

import EmblaCarousel from 'embla-carousel'

const emblaNode = document.querySelector('.embla')
const emblaApi = EmblaCarousel(emblaNode)

function logSlidesInViewOnce(emblaApi) {
  console.log(emblaApi.slidesInView())
  emblaApi.off('slidesInView', logSlidesInViewOnce)
}

emblaApi.on('slidesInView', logSlidesInViewOnce)
import { useCallback, useEffect } from 'react'
import useEmblaCarousel from 'embla-carousel-react'

export function EmblaCarousel() {
  const [emblaRef, emblaApi] = useEmblaCarousel()

  const logSlidesInViewOnce = useCallback((emblaApi) => {
    console.log(emblaApi.slidesInView())
    emblaApi.off('slidesInView', logSlidesInViewOnce)
  }, [])

  useEffect(() => {
    if (emblaApi) emblaApi.on('slidesInView', logSlidesInViewOnce)
  }, [emblaApi, logSlidesInViewOnce])

  // ...
}
<script setup>
  import { onMounted } from 'vue'
  import emblaCarouselVue from 'embla-carousel-vue'

  const [emblaRef, emblaApi] = emblaCarouselVue()

  function logSlidesInViewOnce(emblaApi) {
    console.log(emblaApi.slidesInView())
    emblaApi.off('slidesInView', logSlidesInViewOnce)
  }

  onMounted(() => {
    if (emblaApi.value) emblaApi.value.on('slidesInView', logSlidesInViewOnce)
  })

  // ...
</script>
import { onMount } from 'solid-js'
import createEmblaCarousel from 'embla-carousel-solid'

export function EmblaCarousel() {
  const [emblaRef, emblaApi] = createEmblaCarousel()

  function logSlidesInViewOnce(emblaApi) {
    console.log(emblaApi.slidesInView())
    emblaApi.off('slidesInView', logSlidesInViewOnce)
  }

  onMount(() => {
    const api = emblaApi()
    if (api) api.on('slidesInView', logSlidesInViewOnce)
  })

  // ...
}
<script>
  import emblaCarouselSvelte from 'embla-carousel-svelte'

  let emblaApi

  function logSlidesInViewOnce(emblaApi) {
    console.log(emblaApi.slidesInView())
    emblaApi.off('slidesInView', logSlidesInViewOnce)
  }

  function onInit(event) {
    emblaApi = event.detail
    emblaApi.on('slidesInView', logSlidesInViewOnce)
  }
</script>

<div class="embla" use:emblaCarouselSvelte on:emblaInit="{onInit}">...</div>

TypeScript

The EmblaEventType is obtained directly from the core package embla-carousel and used like so:

import EmblaCarousel, {
  EmblaCarouselType,
  EmblaEventType
} from 'embla-carousel'

const emblaNode = document.querySelector('.embla')
const emblaApi = EmblaCarousel(emblaNode)

function logEmblaEvent(
  emblaApi: EmblaCarouselType,
  eventName: EmblaEventType
): void {
  console.log(`Embla just triggered ${eventName}!`)
}

emblaApi.on('slidesInView', logEmblaEvent)
import React, { useCallback } from 'react'
import { EmblaCarouselType, EmblaEventType } from 'embla-carousel'
import useEmblaCarousel from 'embla-carousel-react'

export function EmblaCarousel() {
  const [emblaRef, emblaApi] = useEmblaCarousel()

  const logEmblaEvent = useCallback(
    (emblaApi: EmblaCarouselType, eventName: EmblaEventType) => {
      console.log(`Embla just triggered ${eventName}!`)
    },
    []
  )

  useEffect(() => {
    if (emblaApi) emblaApi.on('slidesInView', logEmblaEvent)
  }, [emblaApi, logEmblaEvent])

  // ...
}
If you're using `pnpm`, you need to install `embla-carousel` as a **devDependency** when importing types from it like demonstrated above.
This is because even though `embla-carousel-react` has `embla-carousel` as a dependency, `pnpm` makes nested dependencies inaccessible by design.
<script setup>
  import { onMounted } from 'vue'
  import { EmblaCarouselType, EmblaEventType } from 'embla-carousel'
  import emblaCarouselVue from 'embla-carousel-vue'

  const [emblaRef] = emblaCarouselVue()

  function logEmblaEvent(
    emblaApi: EmblaCarouselType,
    eventName: EmblaEventType
  ): void {
    console.log(`Embla just triggered ${eventName}!`)
  }

  onMounted(() => {
    if (emblaApi.value) emblaApi.value.on('slidesInView', logEmblaEvent)
  })

  // ...
</script>
If you're using `pnpm`, you need to install `embla-carousel` as a **devDependency** when importing types from it like demonstrated above.
This is because even though `embla-carousel-vue` has `embla-carousel` as a dependency, `pnpm` makes nested dependencies inaccessible by design.
import { onMount } from 'solid-js'
import { EmblaCarouselType, EmblaEventType } from 'embla-carousel'
import createEmblaCarousel from 'embla-carousel-solid'

export function EmblaCarousel() {
  const [emblaRef, emblaApi] = createEmblaCarousel()

  function logEmblaEvent(
    emblaApi: EmblaCarouselType,
    eventName: EmblaEventType
  ): void {
    console.log(`Embla just triggered ${eventName}!`)
  }

  onMount(() => {
    const api = emblaApi()
    if (api) api.on('slidesInView', logEmblaEvent)
  })

  // ...
}
If you're using `pnpm`, you need to install `embla-carousel` as a **devDependency** when importing types from it like demonstrated above.
This is because even though `embla-carousel-solid` has `embla-carousel` as a dependency, `pnpm` makes nested dependencies inaccessible by design.
<script>
  import { EmblaCarouselType, EmblaEventType } from 'embla-carousel'
  import emblaCarouselSvelte from 'embla-carousel-svelte'

  let emblaApi: EmblaCarouselType

  function logEmblaEvent(
    emblaApi: EmblaCarouselType,
    eventName: EmblaEventType
  ): void {
    console.log(`Embla just triggered ${eventName}!`)
  }

  function onInit(event): void {
    emblaApi = event.detail
    emblaApi.on('slidesInView', logEmblaEvent)
  }
</script>

<div class="embla" use:emblaCarouselSvelte on:emblaInit="{onInit}">...</div>
If you're using `pnpm`, you need to install `embla-carousel` as a **devDependency** when importing types from it like demonstrated above.
This is because even though `embla-carousel-svelte` has `embla-carousel` as a dependency, `pnpm` makes nested dependencies inaccessible by design.

Reference

Below follows an exhaustive list of all Embla Carousel events together with information about how they work.


init

Once: yes

Runs when the carousel mounts for the first time. This only fires once which means that it won't fire when the carousel is re-initialized using the reInit method.


reInit

Once: no

Runs when the reInit method is called. When the window is resized, Embla Carousel automatically calls the reInit method which will also fire this event.


destroy

Once: yes

Runs when the carousel has been destroyed using the destroy method. This only fires once and will be the last event the carousel fires.


select

Once: no

Runs when the selected scroll snap changes. The select event is triggered by drag interactions or the scrollNext, scrollPrev or scrollTo methods.


scroll

Once: no

Runs when the carousel is scrolling. It might be a good idea to throttle this if you're doing expensive stuff in your callback function.


settle

Once: no

Runs when the carousel has settled after scroll has been triggered. Please note that this can take longer than you think when dragFree is enabled or when using slow transitions.


resize

Once: no

Runs when the carousel container or the slide sizes change. It's using ResizeObserver under the hood.


slidesInView

Once: no

Runs when any slide has entered or exited the viewport. This event is intended to be used together with the slidesInView and/or slidesNotInView methods.


slidesChanged

Once: no

Runs when slides are added to, or removed from the carousel container. It's using MutationObserver under the hood.


pointerDown

Once: no

Runs when the user has a pointer down on the carousel. It's triggered by a touchstart or a mousedown event.


pointerUp

Once: no

Runs when the user has released the pointer from the carousel. It's triggered by a touchend or a mouseup event.