Skip to content

useScroll

Category
Export Size
1.53 kB
Last Changed
last month

Reactive scroll position and state.

Demo

TopLeft
BottomLeft
TopRight
BottomRight
Scroll Me
X Position
Y Position
isScrollingfalse
Top Arrived
true
Right Arrived
false
Bottom Arrived
false
Left Arrived
true
Scrolling Up
false
Scrolling Right
false
Scrolling Down
false
Scrolling Left
false

Usage

vue
<script setup lang="ts">
import { useScroll } from '@vueuse/core'

const el = ref<HTMLElement | null>(null)
const { x, y, isScrolling, arrivedState, directions } = useScroll(el)
</script>

<template>
  <div ref="el" />
</template>

With offsets

js
const { x, y, isScrolling, arrivedState, directions } = useScroll(el, {
  offset: { top: 30, bottom: 30, right: 30, left: 30 },
})

Setting scroll position

Set the x and y values to make the element scroll to that position.

vue
<script setup lang="ts">
import { useScroll } from '@vueuse/core'

const el = ref<HTMLElement | null>(null)
const { x, y } = useScroll(el)
</script>

<template>
  <div ref="el" />
  <button @click="x += 10">
    Scroll right 10px
  </button>
  <button @click="y += 10">
    Scroll down 10px
  </button>
</template>

Smooth scrolling

Set behavior: smooth to enable smooth scrolling. The behavior option defaults to auto, which means no smooth scrolling. See the behavior option on window.scrollTo() for more information.

ts
import { useScroll } from '@vueuse/core'

const el = ref<HTMLElement | null>(null)
const { x, y } = useScroll(el, { behavior: 'smooth' })

// Or as a `ref`:
const smooth = ref(false)
const behavior = computed(() => smooth.value ? 'smooth' : 'auto')
const { x, y } = useScroll(el, { behavior })
js
import { useScroll } from '@vueuse/core'
const el = ref(null)
const { x, y } = useScroll(el, { behavior: 'smooth' })
// Or as a `ref`:
const smooth = ref(false)
const behavior = computed(() => (smooth.value ? 'smooth' : 'auto'))
const { x, y } = useScroll(el, { behavior })

Directive Usage

This function also provides a directive version via the @vueuse/components package. Learn more about the usage.

vue
<script setup lang="ts">
import type { UseScrollReturn } from '@vueuse/core'
import { vScroll } from '@vueuse/components'

const data = ref([1, 2, 3, 4, 5, 6])

function onScroll(state: UseScrollReturn) {
  console.log(state) // {x, y, isScrolling, arrivedState, directions}
}
</script>

<template>
  <div v-scroll="onScroll">
    <div v-for="item in data" :key="item">
      {{ item }}
    </div>
  </div>

  <!-- with options -->
  <div v-scroll="[onScroll, { throttle: 10 }]">
    <div v-for="item in data" :key="item">
      {{ item }}
    </div>
  </div>
</template>

Type Declarations

Show Type Declarations
typescript
export interface UseScrollOptions extends ConfigurableWindow {
  /**
   * Throttle time for scroll event, it’s disabled by default.
   *
   * @default 0
   */
  throttle?: number
  /**
   * The check time when scrolling ends.
   * This configuration will be setting to (throttle + idle) when the `throttle` is configured.
   *
   * @default 200
   */
  idle?: number
  /**
   * Offset arrived states by x pixels
   *
   */
  offset?: {
    left?: number
    right?: number
    top?: number
    bottom?: number
  }
  /**
   * Trigger it when scrolling.
   *
   */
  onScroll?: (e: Event) => void
  /**
   * Trigger it when scrolling ends.
   *
   */
  onStop?: (e: Event) => void
  /**
   * Listener options for scroll event.
   *
   * @default {capture: false, passive: true}
   */
  eventListenerOptions?: boolean | AddEventListenerOptions
  /**
   * Optionally specify a scroll behavior of `auto` (default, not smooth scrolling) or
   * `smooth` (for smooth scrolling) which takes effect when changing the `x` or `y` refs.
   *
   * @default 'auto'
   */
  behavior?: MaybeRefOrGetter<ScrollBehavior>
  /**
   * On error callback
   *
   * Default log error to `console.error`
   */
  onError?: (error: unknown) => void
}
/**
 * Reactive scroll.
 *
 * @see https://vueuse.org/useScroll
 * @param element
 * @param options
 */
export declare function useScroll(
  element: MaybeRefOrGetter<
    HTMLElement | SVGElement | Window | Document | null | undefined
  >,
  options?: UseScrollOptions,
): {
  x: WritableComputedRef<number>
  y: WritableComputedRef<number>
  isScrolling: Ref<boolean>
  arrivedState: {
    left: boolean
    right: boolean
    top: boolean
    bottom: boolean
  }
  directions: {
    left: boolean
    right: boolean
    top: boolean
    bottom: boolean
  }
  measure(): void
}
export type UseScrollReturn = ReturnType<typeof useScroll>

Source

SourceDemoDocs

Contributors

Anthony Fu
webfansplz
Curt Grimes
Dima Kaltovich
Poet
Nico Prat
MinatoHikari
Vladimir
AlanYu
Scott Bedard
Christian Martinez
kongmoumou
丶远方
holtergram
Ayaka Rizumu
云游君
btea
Thierry Michel
Pavel Yankovski
Bobakanoosh
Joseph Fitz Hughes

Changelog

v10.8.0 on 2/20/2024
fab86 - fix: add onError hook and avoid throws by default, fix #3580 (#3605)
v10.6.1 on 11/13/2023
e9742 - fix: can not read properties of null (reading document) (#3544)
v10.6.0 on 11/9/2023
86bd8 - fix: trigger once onMounted to get correct inital arrivedStates values (#3384)
v10.4.0 on 8/25/2023
c1b29 - fix: evade edge case when window or document is Proxy (#3280)
v10.3.0 on 7/30/2023
dde41 - fix: support configurable window (#3229)
v10.2.0 on 6/16/2023
8855f - fix: support window in setArrivedState (#3086)
v10.1.1 on 5/1/2023
a88fe - fix(useInfiniteScroll): re-measure arrived states when async infinite scroll resolves (#3030)
v10.0.0-beta.4 on 4/13/2023
23b9a - fix: add support for row-reverse and column-reverse (#2577)
4d757 - feat(types)!: rename MaybeComputedRef to MaybeRefOrGetter
0a72b - feat(toValue): rename resolveUnref to toValue
v9.13.0 on 2/18/2023
f8872 - feat: support scrollend event (#2716)
v9.5.0 on 11/9/2022
9cd92 - fix: the expected result cannot be returned after setting the throttle parameter (#2390)
v9.3.0 on 9/26/2022
324ff - feat: support setting scroll position and toggling smooth scrolling (#1996)
v9.1.1 on 8/23/2022
53a20 - fix: account for rounding errors when calculating arrivedState (#2051)

Released under the MIT License.