Skip to content

Commit

Permalink
feat(useScroll): add useScroll
Browse files Browse the repository at this point in the history
  • Loading branch information
lmhcoding committed Sep 19, 2020
1 parent 9bc82da commit 70b2a3a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './useTitle'
export * from './useEvent'
export * from './useScroll'
25 changes: 13 additions & 12 deletions src/useEvent.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable no-redeclare */
import { Ref, onMounted, onUnmounted, isRef, getCurrentInstance } from 'vue'
import { Ref, onMounted, onUnmounted, isRef, getCurrentInstance, shallowRef } from 'vue'

type Target = Ref<EventTarget> | EventTarget | string
export type Target = Ref<EventTarget> | EventTarget | string

interface WindowEventHandler<T extends keyof WindowEventMap> {
(this: Window, e: WindowEventMap[T]): any
Expand All @@ -15,17 +15,17 @@ type HandlerOptions = boolean | AddEventListenerOptions
type DocumentEvents = keyof DocumentEventMap
type WindowEvents = keyof WindowEventMap

function getTarget(target: Target): EventTarget | null {
function getTarget(target: Target): EventTarget {
if (!target) {
return window
}
if (typeof target === 'string') {
const dom = document.querySelector(target)
if (!dom && process.env.NODE_ENV !== 'production') {
console.error('target is not found')
return null
throw Error(`target of selector ${target} is not found`)
}
return dom
return dom!
}
if (isRef(target)) {
return target.value
Expand All @@ -50,19 +50,19 @@ export function useEvent<T extends WindowEvents>(
event: T,
handler: WindowEventHandler<T>,
options?: HandlerOptions
): void
): Ref<EventTarget>
export function useEvent<T extends DocumentEvents>(
event: T,
handler: DocumentEventHandler<T>,
options?: HandlerOptions,
target?: Target
): void
): Ref<EventTarget>
export function useEvent<T extends DocumentEvents>(
event: T,
handler: DocumentEventHandler<T>,
options?: HandlerOptions,
target?: string
): void
): Ref<EventTarget>
export function useEvent(
event: string,
cb: EventListenerOrEventListenerObject,
Expand All @@ -72,9 +72,9 @@ export function useEvent(
if (!event || !cb) {
return
}
let eventTarget: EventTarget | null
const eventTarget: Ref<EventTarget | null> = shallowRef(null)
function register() {
eventTarget = registerEvent(target, event, cb, options)
eventTarget.value = registerEvent(target, event, cb, options)
}
const currentInstance = getCurrentInstance()
if (currentInstance) {
Expand All @@ -86,9 +86,10 @@ export function useEvent(
})
}
onUnmounted(() => {
if (eventTarget) {
eventTarget.removeEventListener(event, cb)
if (eventTarget.value) {
eventTarget.value.removeEventListener(event, cb)
}
})
}
return eventTarget
}
29 changes: 29 additions & 0 deletions src/useScroll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { reactive, toRefs, ToRefs } from 'vue'
import { useEvent, Target } from './useEvent'

export type ScrollState = ToRefs<{
x: number
y: number
}>

export function useScroll(target: Target): ScrollState {
if (target === window && process.env.NODE_ENV !== 'production') {
throw Error('target of useScroll should not be window')
}
const state = reactive({
x: 0,
y: 0
})
const eventTarget = useEvent(
'scroll',
() => {
if (eventTarget.value) {
state.x = ((eventTarget.value as unknown) as Element).scrollLeft
state.y = ((eventTarget.value as unknown) as Element).scrollTop
}
},
{ capture: false, passive: true },
target
)
return toRefs(state)
}

0 comments on commit 70b2a3a

Please sign in to comment.