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 };
|
|||
|
|
}
|