vuux
Version:
Vue3 Nuxt3 Nuxt4 组件库
76 lines (75 loc) • 2.68 kB
JavaScript
import { ref as a, computed as p, onMounted as b, nextTick as z, onUnmounted as E } from "vue";
const y = (n, o, f) => {
const c = a(window), i = a(!1), v = a(!1), d = a(0), r = a(0);
let g = null;
const B = (e) => {
let t = e.parentElement;
for (; t; ) {
const l = window.getComputedStyle(t);
if (/(scroll|auto)/.test(l.overflowY))
return t;
t = t.parentElement;
}
return window;
}, x = (e) => e instanceof Window ? window.scrollY : e.scrollTop, C = p(() => i.value ? { height: d.value + "px", width: r.value + "px" } : {}), T = p(() => {
if (!i.value)
return {};
const e = c.value, t = {
width: r.value + "px",
zIndex: n.zIndex
};
if (e instanceof HTMLElement)
if (t.position = "absolute", n.position === "top")
t.top = e.scrollTop + n.offset + "px";
else {
const l = o.value.getBoundingClientRect(), u = e.getBoundingClientRect(), s = e.scrollHeight - (l.top + l.height - u.top);
t.bottom = s < n.offset ? n.offset + "px" : s + "px";
}
else
t.position = "fixed", n.position === "top" ? t.top = n.offset + "px" : t.bottom = n.offset + "px";
return t;
}), m = () => {
if (!o.value || !c.value)
return;
const e = c.value, t = x(e);
let l = !1;
if (n.position === "top") {
const u = o.value.getBoundingClientRect(), s = e instanceof Window ? 0 : e.getBoundingClientRect().top;
l = u.top + t - s <= t + n.offset;
} else {
const u = o.value.getBoundingClientRect();
if (e instanceof Window) {
const s = window.innerHeight;
l = u.bottom >= s - n.offset;
} else
l = e.getBoundingClientRect().bottom - u.bottom <= n.offset;
}
l !== i.value && (i.value = l, f("change", i.value)), f("scroll", { scrollTop: t, fixed: i.value });
}, h = () => {
v.value || (requestAnimationFrame(() => {
m(), v.value = !1;
}), v.value = !0);
}, w = () => {
if (!o.value)
return;
const e = o.value.getBoundingClientRect();
d.value = e.height, r.value = e.width, i.value && m();
};
return b(() => {
z(() => {
if (!o.value)
return;
c.value = B(o.value);
const e = o.value.getBoundingClientRect();
d.value = e.height, r.value = e.width, i.value = !1, c.value.addEventListener("scroll", h, { passive: !0 }), window.addEventListener("resize", w), g = new ResizeObserver(w), g.observe(o.value);
});
}), E(() => {
c.value?.removeEventListener("scroll", h), window.removeEventListener("resize", w), g?.disconnect();
}), {
affixStyle: T,
affixRefStyle: C
};
};
export {
y as useAffix
};