feat(use): add useScrollParent

This commit is contained in:
chenjiahan
2020-09-12 22:04:02 +08:00
parent 68817e3aba
commit ecbaddd5e1
8 changed files with 91 additions and 52 deletions

View File

@@ -1,3 +1,4 @@
export { useToggle } from './useToggle';
export { useClickAway } from './useClickAway';
export { useScrollParent } from './useScrollParent';
export { useEventListener } from './useEventListener';

View File

@@ -0,0 +1,51 @@
import { ref, Ref, onMounted } from 'vue';
type ScrollElement = HTMLElement | Window;
const overflowScrollReg = /scroll|auto/i;
function isElement(node: Element) {
const ELEMENT_NODE_TYPE = 1;
return node.tagName !== 'HTML' && node.nodeType === ELEMENT_NODE_TYPE;
}
// http://w3help.org/zh-cn/causes/SD9013
// http://stackoverflow.com/questions/17016740/onscroll-function-is-not-working-for-chrome
export function getScrollParent(el: Element, root: ScrollElement = window) {
let node = el;
while (node && node !== root && isElement(node)) {
const { overflowY } = window.getComputedStyle(node);
if (overflowScrollReg.test(overflowY)) {
if (node.tagName !== 'BODY') {
return node;
}
// see: https://github.com/youzan/vant/issues/3823
const { overflowY: htmlOverflowY } = window.getComputedStyle(
node.parentNode as Element
);
if (overflowScrollReg.test(htmlOverflowY)) {
return node;
}
}
node = node.parentNode as Element;
}
return root;
}
export function useScrollParent(el: Ref<Element>) {
const scrollParent = ref();
onMounted(() => {
if (el.value) {
scrollParent.value = getScrollParent(el.value);
}
});
return scrollParent;
}