10000 fix(useScroll): use mutationObserver to update arrivedState when the DOM is changed by andylou0102 · Pull Request #4433 · vueuse/vueuse · GitHub
[go: up one dir, main page]

Skip to content

fix(useScroll): use mutationObserver to update arrivedState when the DOM is changed #4433

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

Merged
merged 11 commits into from
Jun 19, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fix: add useMutationObserver in useScroll
  • Loading branch information
AndyLuo authored and AndyLuo committed Dec 26, 2024
commit ba1d0f9904306b0fd1c070abe4e9db121b4619a4
26 changes: 26 additions & 0 deletions packages/core/useScroll/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { noop, tryOnMounted, useDebounceFn, useThrottleFn } from '@vueuse/shared
import { computed, reactive, ref, toValue } from 'vue'
import { defaultWindow } from '../_configurable'
import { unrefElement } from '../unrefElement'
import { useMutationObserver } from '../useMutationObserver'
import { useEventListener } from '../useEventListener'

export interface UseScrollOptions extends ConfigurableWindow {
Expand Down Expand Up @@ -33,6 +34,13 @@ export interface UseScrollOptions extends ConfigurableWindow {
bottom?: number
}

/**
* Use MutationObserver to monitor specific DOM changes,
* such as attribute modifications, child node additions or removals, or subtree changes.
* @default false
*/
observe?: boolean
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

regarding #4655

lets maybe do

Suggested change
observe?: boolean
observe?: boolean | {mutation: boolean}

so we can have {mutation: boolean, resize: boolean} with #4655

Like this we can merge this PR and update #4655 to support this :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andylou0102 I think if we add this, we can merge this soon 😃

Copy link
Contributor Author
@andylou0102 andylou0102 Apr 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, the observe option has been updated to boolean | { mutation: boolean } to support more specific observation settings and provide extensibility for #4655 in future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@OrbisK I wrote a piece of logic to construct observe, aiming to allow users to control it in a simple way (without worrying about whether it's mutation or resize), while internally unifying it into an object for distinction.

In my opinion, after adding resize, it would look like this :

const observe = typeof _observe === 'boolean'
  ? {
      mutation: _observe,
      resize: _observe
    }
  : _observe;

Passing a boolean will toggle both mutation and resize at the same time. If the user needs fine-grained control, they can pass an object to configure it manually.
commit


/**
* Trigger it when scrolling.
*
Expand Down Expand Up @@ -98,6 +106,7 @@ export function useScroll(
top: 0,
bottom: 0,
},
observe = false,
eventListenerOptions = {
capture: false,
passive: true,
Expand Down Expand Up @@ -279,6 +288,23 @@ export function useScroll(
}
})

if (observe) {
useMutationObserver(
element,
() => {
const _element = toValue(element);
if (!_element)
return;
setArrivedState(_element);
},
{
attributes: true,
childList: true,
subtree: true,
}
);
}

useEventListener(
element,
'scrollend',
Expand Down
0