Skip to content

Commit

Permalink
fix: 修复Select等组件的弹出层不跟随滚动 (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
wanchun authored Apr 29, 2022
1 parent f278f4a commit 699d2ac
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
38 changes: 38 additions & 0 deletions components/_util/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,41 @@ export const pxfy = (value: string | number) => {
if (value.endsWith('px')) return value;
return `${value}px`;
};

export function getParentNode(node: Node): Node | null {
// document type
if (node.nodeType === 9) {
return null;
}
return node.parentNode;
}

export function getScrollParent(
node: Node | null,
): HTMLElement | Document | null {
if (node === null) return null;

const parentNode = getParentNode(node);

if (parentNode === null) {
return null;
}

// Document
if (parentNode.nodeType === 9) {
return document;
}

// Element
if (parentNode.nodeType === 1) {
// Firefox want us to check `-x` and `-y` variations as well
const { overflow, overflowX, overflowY } = getComputedStyle(
parentNode as HTMLElement,
);
if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
return parentNode as HTMLElement;
}
}

return getScrollParent(parentNode);
}
13 changes: 13 additions & 0 deletions components/popper/popper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import getElementFromRef from '../_util/getElementFromRef';
import { useTheme } from '../_theme/useTheme';
import useTrigger from './useTrigger';
import usePopper from './usePopper';
import useScroll from './useScroll';

import { useConfig } from '../config-provider';

Expand Down Expand Up @@ -47,6 +48,18 @@ export default defineComponent({
updateVirtualRect,
placement,
} = usePopper(props, emit);

useScroll(
computed(() => getElementFromRef(triggerRef.value)),
(e: Event) => {
// 不挂载在container上
if (!props.appendToContainer) return;
if (!visible.value) return;
if (e.target === getContainer.value?.()) return;
computePopper();
},
);

const disabledWatch = computed(() => props.disabled || !visible.value);
useClickOutSide(
[triggerRef, popperRef],
Expand Down
37 changes: 37 additions & 0 deletions components/popper/useScroll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Ref, onMounted, onUnmounted } from 'vue';
import { getScrollParent } from '../_util/utils';

export default function useScroll(
targetRef: Ref<HTMLElement>,
onScroll: (e: Event) => void,
) {
// scroll related
let scrollableNodes: Array<Element | Document> = [];

const ensureScrollListener = (): void => {
let cursor: Element | Document | null = targetRef.value;
while (true) {
cursor = getScrollParent(cursor);
if (cursor === null) break;
scrollableNodes.push(cursor);
}
for (const el of scrollableNodes) {
el.addEventListener('scroll', onScroll, true);
}
};

const removeScrollListeners = (): void => {
for (const el of scrollableNodes) {
el.removeEventListener('scroll', onScroll, true);
}
scrollableNodes = [];
};

onMounted(() => {
ensureScrollListener();
});

onUnmounted(() => {
removeScrollListeners();
});
}

0 comments on commit 699d2ac

Please sign in to comment.