-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(useScroll): add onError
hook and avoid throws by default, fix #3580
#3605
Changes from all commits
315d692
974c177
2173b85
cabd9da
7142d23
f60ad6d
2becec2
801181e
0cd918c
f75c8b1
f56331f
31e90d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ import { computed, reactive, ref } from 'vue-demi' | |
import type { MaybeRefOrGetter } from '@vueuse/shared' | ||
import { noop, toValue, tryOnMounted, useDebounceFn, useThrottleFn } from '@vueuse/shared' | ||
import { useEventListener } from '../useEventListener' | ||
import { unrefElement } from '../unrefElement' | ||
import type { ConfigurableWindow } from '../_configurable' | ||
import { defaultWindow } from '../_configurable' | ||
|
||
|
@@ -58,6 +59,13 @@ export interface UseScrollOptions extends ConfigurableWindow { | |
* @default 'auto' | ||
*/ | ||
behavior?: MaybeRefOrGetter<ScrollBehavior> | ||
|
||
/** | ||
* On error callback | ||
* | ||
* Default log error to `console.error` | ||
*/ | ||
onError?: (error: unknown) => void | ||
} | ||
|
||
/** | ||
|
@@ -97,6 +105,7 @@ export function useScroll( | |
}, | ||
behavior = 'auto', | ||
window = defaultWindow, | ||
onError = (e) => { console.error(e) }, | ||
} = options | ||
|
||
const internalX = ref(0) | ||
|
@@ -169,19 +178,19 @@ export function useScroll( | |
if (!window) | ||
return | ||
|
||
const el = ( | ||
(target as Window).document | ||
? (target as Window).document.documentElement | ||
: (target as Document).documentElement ?? target | ||
) as HTMLElement | ||
const el: Element = ( | ||
(target as Window)?.document?.documentElement | ||
|| (target as Document)?.documentElement | ||
|| unrefElement(target as HTMLElement | SVGElement) | ||
) as Element | ||
|
||
const { display, flexDirection } = getComputedStyle(el) | ||
|
||
const scrollLeft = el.scrollLeft | ||
directions.left = scrollLeft < internalX.value | ||
directions.right = scrollLeft > internalX.value | ||
|
||
const left = Math.abs(scrollLeft) <= 0 + (offset.left || 0) | ||
const left = Math.abs(scrollLeft) <= (offset.left || 0) | ||
const right = Math.abs(scrollLeft) | ||
+ el.clientWidth >= el.scrollWidth | ||
- (offset.right || 0) | ||
|
@@ -206,7 +215,7 @@ export function useScroll( | |
|
||
directions.top = scrollTop < internalY.value | ||
directions.bottom = scrollTop > internalY.value | ||
const top = Math.abs(scrollTop) <= 0 + (offset.top || 0) | ||
const top = Math.abs(scrollTop) <= (offset.top || 0) | ||
const bottom = Math.abs(scrollTop) | ||
+ el.clientHeight >= el.scrollHeight | ||
- (offset.bottom || 0) | ||
|
@@ -251,11 +260,15 @@ export function useScroll( | |
) | ||
|
||
tryOnMounted(() => { | ||
const _element = toValue(element) | ||
if (!_element) | ||
return | ||
|
||
setArrivedState(_element) | ||
try { | ||
const _element = toValue(element) | ||
if (!_element) | ||
return | ||
setArrivedState(_element) | ||
} | ||
catch (e) { | ||
onError(e) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure about the try cache here. Ideally we should make it safe. If it's an error that not possible to workaround, I'd prefer to expose a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point 👍🏻
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. But the first thing is how would the error get triggered here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like the root of the problem was highlighted by brendomaciel 👇🏻#3605 (comment) |
||
}) | ||
|
||
useEventListener( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be the root of the problem 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Sorry for the lack of explanation.
The problem occurs because, when using
ref
with components, its value is a component instance instead of the component's root element1. Naturally, sincegetComputedStyle
doesn't exist on the instance object, an error is thrown.Luckily, VueUse already have something to handle this, the
unrefElement
2 that I used in the suggestion.Footnotes
https://vuejs.org/guide/essentials/template-refs.html#ref-on-component ↩
https://vueuse.org/core/unrefElement/#unrefelement ↩