46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
/*
|
||
* @file /src/vue3/hooks/top-sticky.ts
|
||
* @description 吸顶工具
|
||
* @author tsl (randy1924@163.com)
|
||
* @date 2026-03-20 17:51:50
|
||
* @lastModified 2026-03-26 10:24:21
|
||
* @lastModifiedBy tsl (randy1924@163.com)
|
||
*/
|
||
|
||
import { ref } from "vue";
|
||
|
||
export interface UseTopStickyOptions {
|
||
context?: never;
|
||
offsetTop?: number;
|
||
targetSelector: string;
|
||
onToTopChange?: (toTop: boolean) => void;
|
||
}
|
||
|
||
export function useTopSticky(options: UseTopStickyOptions) {
|
||
const context = options.context;
|
||
const offsetTop = options.offsetTop ?? 0;
|
||
const targetSelector = options.targetSelector;
|
||
const onToTopChange = options.onToTopChange;
|
||
|
||
// 是否达到了顶部
|
||
const isToTop = ref(false);
|
||
|
||
const systemInfo = uni.getSystemInfoSync();
|
||
const intersectionObserver = uni.createIntersectionObserver(context);
|
||
|
||
// 观察目标元素
|
||
intersectionObserver
|
||
.relativeToViewport({
|
||
top: 0,
|
||
bottom: -systemInfo.windowHeight + offsetTop,
|
||
})
|
||
.observe(targetSelector, (res) => {
|
||
console.log("intersectionObserver", res);
|
||
// 当目标与视口顶部距离小于0px时,isToTop 设为 true
|
||
isToTop.value = res.intersectionRatio > 0;
|
||
onToTopChange?.(isToTop.value);
|
||
});
|
||
|
||
return { isToTop };
|
||
}
|