UNPKG

xdesign-vue-next

Version:

XDesign Component for vue-next

1 lines 13.7 kB
{"version":3,"file":"anchor.mjs","sources":["../../src/anchor/anchor.tsx"],"sourcesContent":["import {\n defineComponent,\n nextTick,\n ComponentPublicInstance,\n ref,\n reactive,\n onMounted,\n onUnmounted,\n watchEffect,\n provide,\n} from 'vue';\nimport { ANCHOR_SHARP_REGEXP, ANCHOR_CONTAINER, getOffsetTop } from './utils';\nimport { isServer, on, off, getScroll, scrollTo, getScrollContainer as utilsGetScrollContainer } from '../utils/dom';\nimport props from './props';\nimport { useTNodeJSX } from '../hooks/tnode';\nimport { SlotReturnValue } from '../common';\nimport Affix from '../affix';\nimport { TdAnchorProps } from './type';\nimport { usePrefixClass, useCommonClassName } from '../hooks/useConfig';\nimport { AnchorInjectionKey } from './constants';\n\nexport interface Anchor extends ComponentPublicInstance {\n scrollContainer: ANCHOR_CONTAINER;\n // 执行scrollTo设置的flag, 用来禁止执行handleScroll\n handleScrollLock: boolean;\n}\n\nexport default defineComponent({\n name: 'XAnchor',\n inheritAttrs: false,\n props,\n setup(props: TdAnchorProps, { attrs }) {\n const anchorRef = ref<HTMLElement | null>(null);\n const links = ref<string[]>([]);\n const active = ref('');\n const scrollContainer = ref<ANCHOR_CONTAINER>(null);\n const handleScrollLock = ref<boolean>(false);\n const activeLineStyle = reactive({});\n const COMPONENT_NAME = usePrefixClass('anchor');\n const ANCHOR_LINE_CLASSNAME = usePrefixClass('anchor__line');\n const ANCHOR_LINE_CURSOR_CLASSNAME = usePrefixClass('anchor__line-cursor');\n const { STATUS, SIZE } = useCommonClassName();\n const renderTNodeJSX = useTNodeJSX();\n /**\n * 获取滚动容器\n * 1. 如果是string则通过id获取\n * 2. 如果是method则获取方法返回值\n */\n const getScrollContainer = () => {\n if (isServer) {\n return;\n }\n const { container } = props;\n scrollContainer.value = utilsGetScrollContainer(container) as HTMLElement;\n on(scrollContainer.value, 'scroll', handleScroll);\n handleScroll();\n };\n /**\n * 监听滚动事件\n */\n const handleScroll = () => {\n if (handleScrollLock.value) return;\n const { bounds, targetOffset } = props;\n const filters: { top: number; link: string }[] = [];\n let active = '';\n // 找出所有当前top小于预设值\n links.value.forEach((link) => {\n const anchor = getAnchorTarget(link);\n if (!anchor) {\n return;\n }\n const top = getOffsetTop(anchor, scrollContainer.value);\n if (top < bounds + targetOffset) {\n filters.push({\n link,\n top,\n });\n }\n });\n // 找出小于预设值集合中top最大的\n if (filters.length) {\n const latest = filters.reduce((prev, cur) => (prev.top > cur.top ? prev : cur));\n active = latest.link;\n }\n setCurrentActiveLink(active);\n };\n /**\n * 获取锚点对应的target元素\n *\n * @param {string} link\n */\n const getAnchorTarget = (link: string): HTMLElement => {\n const matcher = link.match(ANCHOR_SHARP_REGEXP);\n if (!matcher) {\n return;\n }\n const anchor = document.getElementById(matcher[1]);\n if (!anchor) {\n return;\n }\n return anchor;\n };\n /**\n * 注册锚点\n *\n * @param {string} link\n */\n const registerLink = (link: string) => {\n if (!ANCHOR_SHARP_REGEXP.test(link) || links.value.indexOf(link) !== -1) {\n return;\n }\n links.value.push(link);\n };\n /**\n * 注销锚点\n *\n * @param {string} link\n */\n const unregisterLink = (link: string) => {\n links.value = links.value.filter((each) => each !== link);\n };\n /**\n * 设置当前激活状态锚点\n *\n * @param {string} link\n */\n const setCurrentActiveLink = async (link: string): Promise<void> => {\n if (active.value === link) {\n return;\n }\n active.value = link;\n props.onChange?.(link, active.value);\n await nextTick();\n updateActiveLine();\n };\n /**\n * 计算active-line所在的位置\n * 当前active-item的top + height, 以及ANCHOR_ITEM_PADDING修正\n */\n const updateActiveLine = () => {\n const ele = anchorRef.value?.querySelector(`.${STATUS.value.active}>a`) as HTMLAnchorElement;\n if (!ele) {\n Object.assign(activeLineStyle, {});\n return;\n }\n const { offsetTop: top, offsetHeight: height } = ele;\n Object.assign(activeLineStyle, {\n top: `${top}px`,\n height: `${height}px`,\n opacity: 1,\n });\n };\n /**\n * 监听AnchorLink点击事件\n * @param {{ href: string; title: string }} link\n */\n const handleLinkClick = (link: { href: string; title: string; e: MouseEvent }) => {\n props.onClick?.(link);\n };\n /**\n * 滚动到指定锚点\n *\n * @param {string} link\n */\n const handleScrollTo = async (link: string): Promise<void> => {\n const anchor = getAnchorTarget(link);\n setCurrentActiveLink(link);\n if (!anchor) return;\n handleScrollLock.value = true;\n const { targetOffset } = props;\n const scrollTop = getScroll(scrollContainer.value);\n const offsetTop = getOffsetTop(anchor, scrollContainer.value);\n const top = scrollTop + offsetTop - targetOffset;\n await scrollTo(top, {\n container: scrollContainer.value,\n });\n handleScrollLock.value = false;\n };\n const renderCursor = () => {\n const titleContent: SlotReturnValue = renderTNodeJSX('cursor');\n return titleContent || <div class={ANCHOR_LINE_CURSOR_CLASSNAME.value}></div>;\n };\n onMounted(async () => {\n getScrollContainer();\n if (active.value) {\n await nextTick();\n handleScrollTo(active.value);\n }\n });\n onUnmounted(() => {\n if (!scrollContainer.value) return;\n off(scrollContainer.value, 'scroll', handleScroll);\n });\n watchEffect(() => {\n // 清空上一个container的事件监听\n if (scrollContainer.value) {\n off(scrollContainer.value, 'scroll', handleScroll);\n }\n getScrollContainer();\n });\n provide(\n AnchorInjectionKey,\n reactive({\n registerLink,\n unregisterLink,\n handleScrollTo,\n handleLinkClick,\n active,\n }),\n );\n return () => {\n const { size, affixProps } = props;\n const className = [COMPONENT_NAME.value, SIZE.value[size]];\n\n const content = (\n <div ref={anchorRef} class={className} {...attrs}>\n <div class={ANCHOR_LINE_CLASSNAME.value}>\n <div class={`${ANCHOR_LINE_CURSOR_CLASSNAME.value}-wrapper`} style={activeLineStyle}>\n {renderCursor()}\n </div>\n </div>\n {renderTNodeJSX('default')}\n </div>\n );\n\n if (affixProps) {\n return <Affix {...affixProps}>{content}</Affix>;\n }\n\n return content;\n };\n },\n});\n"],"names":["_isVNode","name","inheritAttrs","props","setup","getScrollContainer","scrollContainer","handleScroll","links","link","top","_regeneratorRuntime","_context","updateActiveLine","Object","height","opacity","anchor","_context2","scrollTop","_context3","handleScrollTo","onUnmounted","watchEffect","provide","registerLink","unregisterLink","handleLinkClick","active","_createVNode","_mergeProps"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBmC,SAAA,OAAA,CAAA,CAAA,EAAA;AAAA,EAAA,OAAA,OAAA,CAAA,KAAA,UAAA,IAAA,MAAA,CAAA,SAAA,CAAA,QAAA,CAAA,IAAA,CAAA,CAAA,CAAA,KAAA,iBAAA,IAAA,CAAAA,OAAA,CAAA,CAAA,CAAA,CAAA;AAAA,CAAA;AAQnC,cAAA,eAAA,CAAA;AACEC,EAAAA,IAAAA,EAAAA,SAAAA;AACAC,EAAAA,YAAAA,EAAAA,KAAAA;AACAC,EAAAA,KAAAA,EAAAA,KAAAA;AACAC,EAAAA,KAAAA,EAAAA,SAAAA,KAAAA,CAAAA,MAAAA,EAAAA,IAAAA,EAAAA;AAAuC,IAAA,IAAA,KAAA,GAAA,IAAA,CAAA,KAAA,CAAA;AAC/B,IAAA,IAAA,SAAA,GAAA,GAAA,CAAA,IAAA,CAAA,CAAA;AACA,IAAA,IAAA,KAAA,GAAA,GAAA,CAAA,EAAA,CAAA,CAAA;AACA,IAAA,IAAA,MAAA,GAAA,GAAA,CAAA,EAAA,CAAA,CAAA;AACA,IAAA,IAAA,eAAA,GAAA,GAAA,CAAA,IAAA,CAAA,CAAA;AACA,IAAA,IAAA,gBAAA,GAAA,GAAA,CAAA,KAAA,CAAA,CAAA;AACA,IAAA,IAAA,eAAA,GAAA,QAAA,CAAA,EAAA,CAAA,CAAA;AACA,IAAA,IAAA,cAAA,GAAA,cAAA,CAAA,QAAA,CAAA,CAAA;AACA,IAAA,IAAA,qBAAA,GAAA,cAAA,CAAA,cAAA,CAAA,CAAA;AACA,IAAA,IAAA,4BAAA,GAAA,cAAA,CAAA,qBAAA,CAAA,CAAA;AACN,IAAA,IAAA,mBAAA,GAAA,kBAAA,EAAA;;;AACA,IAAA,IAAA,cAAA,GAAA,WAAA,EAAA,CAAA;AAMA,IAAA,IAAAC,oBAAA,GAAA,SAAAA,oBAAA,GAAA;AACE,MAAA,IAAA,QAAA,EAAA;AACE,QAAA,OAAA;AACF,OAAA;AACM,MAAA,IAAA,SAAA,GAAA,MAAA,CAAA,SAAA,CAAA;AACUC,MAAAA,eAAAA,CAAAA,KAAAA,GAAAA,kBAAAA,CAAAA,SAAAA,CAAAA,CAAAA;;AAEHC,MAAAA,YAAAA,EAAAA,CAAAA;;AAKf,IAAA,IAAA,YAAA,GAAA,SAAA,YAAA,GAAA;;AAEQ,MAAA,IAAA,MAAA,GAAA,MAAA,CAAA,MAAA;;;;AAIAC,MAAAA,KAAAA,CAAAA,KAAAA,CAAAA,OAAAA,CAAAA,UAAAA,IAAAA,EAAAA;AACE,QAAA,IAAA,MAAA,GAAA,eAAA,CAAA,IAAA,CAAA,CAAA;;AAEJ,UAAA,OAAA;AACF,SAAA;;AAEI,QAAA,IAAA,GAAA,GAAA,MAAA,GAAA,YAAA,EAAA;;AAEAC,YAAAA,IAAAA,EAAAA,IAAAA;AACAC,YAAAA,GAAAA,EAAAA,GAAAA;AACF,WAAA,CAAA,CAAA;AACF,SAAA;AACF,OAAA,CAAA,CAAA;;;;;;AAKA,OAAA;;;AAQI,IAAA,IAAA,eAAA,GAAA,SAAA,eAAA,CAAA,IAAA,EAAA;AACE,MAAA,IAAA,OAAA,GAAA,IAAA,CAAA,KAAA,CAAA,mBAAA,CAAA,CAAA;;AAEJ,QAAA,OAAA;AACF,OAAA;;;AAGE,QAAA,OAAA;AACF,OAAA;AACO,MAAA,OAAA,MAAA,CAAA;;AAOH,IAAA,IAAA,YAAA,GAAA,SAAA,YAAA,CAAA,IAAA,EAAA;AACA,MAAA,IAAA,CAAA,mBAAA,CAAA,IAAA,CAAA,IAAA,CAAA,IAAA,KAAA,CAAA,KAAA,CAAA,OAAA,CAAA,IAAA,CAAA,KAAA,CAAA,CAAA,EAAA;AACF,QAAA,OAAA;AACF,OAAA;AACMF,MAAAA,KAAAA,CAAAA,KAAAA,CAAAA,IAAAA,CAAAA,IAAAA,CAAAA,CAAAA;;AAOF,IAAA,IAAA,cAAA,GAAA,SAAA,cAAA,CAAA,IAAA,EAAA;;;;;AAQA,IAAA,IAAA,oBAAA,gBAAA,YAAA;;AAA8D,QAAA,IAAA,gBAAA,CAAA;AAAA,QAAA,OAAAG,WAAA,CAAA,IAAA,CAAA,SAAA,QAAA,CAAA,QAAA,EAAA;AAAA,UAAA,OAAA,CAAA,EAAA,QAAA,QAAA,CAAA,IAAA,GAAA,QAAA,CAAA,IAAA;AAAA,YAAA,KAAA,CAAA;AAAA,cAAA,IAAA,EAAA,MAAA,CAAA,KAAA,KAAA,IAAA,CAAA,EAAA;AACvCC,gBAAAA,QAAAA,CAAAA,IAAAA,GAAAA,CAAAA,CAAAA;AAAA,gBAAA,MAAA;AAAA,eAAA;;AAAA,YAAA,KAAA,CAAA;;AAI3BT,cAAAA,CAAAA,gBAAAA,GAAAA,MAAAA,CAAAA,QAAAA,MAAAA,IAAAA,IAAAA,gBAAAA,KAAAA,KAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA,gBAAAA,CAAAA,IAAAA,CAAAA,MAAAA,EAAAA,IAAAA,EAAAA,MAAAA,CAAAA,KAAAA,CAAAA,CAAAA;AAAmCS,cAAAA,QAAAA,CAAAA,IAAAA,GAAAA,CAAAA,CAAAA;;AACpB,YAAA,KAAA,CAAA;AACEC,cAAAA,gBAAAA,EAAAA,CAAAA;AAAA,YAAA,KAAA,CAAA,CAAA;AAAA,YAAA,KAAA,KAAA;;AAAA,WAAA;AAAA,SAAA,EAAA,OAAA,CAAA,CAAA;;;AAPb,QAAA,OAAA,KAAA,CAAA,KAAA,CAAA,IAAA,EAAA,SAAA,CAAA,CAAA;AAAA,OAAA,CAAA;;AAaN,IAAA,IAAA,gBAAA,GAAA,SAAA,gBAAA,GAAA;AAA+B,MAAA,IAAA,gBAAA,CAAA;;;AAGpBC,QAAAA,MAAAA,CAAAA,MAAAA,CAAAA,eAAAA,EAAAA,EAAAA,CAAAA,CAAAA;AACP,QAAA,OAAA;AACF,OAAA;AACA,MAAA,IAAA,GAAA,GAAA,GAAA,CAAA,SAAA;;AACAA,MAAAA,MAAAA,CAAAA,MAAAA,CAAAA,eAAAA,EAAAA;AACEJ,QAAAA,GAAAA,EAAAA,EAAAA,CAAAA,MAAAA,CAAAA,GAAAA,EAAAA,IAAAA,CAAAA;AACAK,QAAAA,MAAAA,EAAAA,EAAAA,CAAAA,MAAAA,CAAAA,MAAAA,EAAAA,IAAAA,CAAAA;AACAC,QAAAA,OAAAA,EAAAA,CAAAA;AACF,OAAA,CAAA,CAAA;;AAMI,IAAA,IAAA,eAAA,GAAA,SAAA,eAAA,CAAA,IAAA,EAAA;AAA4E,MAAA,IAAA,eAAA,CAAA;AAChFb,MAAAA,CAAAA,eAAAA,GAAAA,MAAAA,CAAAA,OAAAA,MAAAA,IAAAA,IAAAA,eAAAA,KAAAA,KAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA,eAAAA,CAAAA,IAAAA,CAAAA,MAAAA,EAAAA,IAAAA,CAAAA,CAAAA;;AAOI,IAAA,IAAA,cAAA,gBAAA,YAAA;;;AAAwD,QAAA,OAAAQ,WAAA,CAAA,IAAA,CAAA,SAAA,SAAA,CAAA,SAAA,EAAA;AAAA,UAAA,OAAA,CAAA,EAAA,QAAA,SAAA,CAAA,IAAA,GAAA,SAAA,CAAA,IAAA;AAAA,YAAA,KAAA,CAAA;AACtDM,cAAAA,MAAAA,GAAAA,eAAAA,CAAAA,IAAAA,CAAAA,CAAAA;;AACmB,cAAA,IAAA,MAAA,EAAA;AACpBC,gBAAAA,SAAAA,CAAAA,IAAAA,GAAAA,CAAAA,CAAAA;AAAA,gBAAA,MAAA;AAAA,eAAA;;AAAA,YAAA,KAAA,CAAA;;;AAGCC,cAAAA,SAAAA,GAAAA,SAAAA,CAAAA,eAAAA,CAAAA,KAAAA,CAAAA,CAAAA;;AAEAT,cAAAA,GAAAA,GAAAA,SAAAA,GAAAA,SAAAA,GAAAA,YAAAA,CAAAA;AAA8BQ,cAAAA,SAAAA,CAAAA,IAAAA,GAAAA,EAAAA,CAAAA;;;AAGpC,eAAA,CAAA,CAAA;AAAC,YAAA,KAAA,EAAA;;AACwB,YAAA,KAAA,EAAA,CAAA;AAAA,YAAA,KAAA,KAAA;;AAAA,WAAA;AAAA,SAAA,EAAA,QAAA,CAAA,CAAA;;;AAZrB,QAAA,OAAA,KAAA,CAAA,KAAA,CAAA,IAAA,EAAA,SAAA,CAAA,CAAA;AAAA,OAAA,CAAA;;AAcN,IAAA,IAAA,YAAA,GAAA,SAAA,YAAA,GAAA;AACQ,MAAA,IAAA,YAAA,GAAA,cAAA,CAAA,QAAA,CAAA,CAAA;;AACiB,QAAA,OAAA,EAAA,4BAAA,CAAA,KAAA;;;;AAEf,MAAA,OAAAP,WAAA,CAAA,IAAA,CAAA,SAAA,SAAA,CAAA,SAAA,EAAA;AAAA,QAAA,OAAA,CAAA,EAAA,QAAA,SAAA,CAAA,IAAA,GAAA,SAAA,CAAA,IAAA;AAAA,UAAA,KAAA,CAAA;AACWN,YAAAA,oBAAAA,EAAAA,CAAAA;;AACDe,cAAAA,SAAAA,CAAAA,IAAAA,GAAAA,CAAAA,CAAAA;AAAA,cAAA,MAAA;AAAA,aAAA;AAAAA,YAAAA,SAAAA,CAAAA,IAAAA,GAAAA,CAAAA,CAAAA;;AACD,UAAA,KAAA,CAAA;AACfC,YAAAA,cAAAA,CAAAA,MAAAA,CAAAA,KAAAA,CAAAA,CAAAA;AAA2B,UAAA,KAAA,CAAA,CAAA;AAAA,UAAA,KAAA,KAAA;;AAAA,SAAA;AAAA,OAAA,EAAA,QAAA,CAAA,CAAA;AAAA,KAAA,CAAA,CAAA,CAAA,CAAA;AAG/BC,IAAAA,WAAAA,CAAAA,YAAAA;AACE,MAAA,IAAA,CAAA,eAAA,CAAA,KAAA,EAAA,OAAA;;AAEF,KAAA,CAAA,CAAA;AACAC,IAAAA,WAAAA,CAAAA,YAAAA;;;AAIE,OAAA;AACmBlB,MAAAA,oBAAAA,EAAAA,CAAAA;AACrB,KAAA,CAAA,CAAA;AACAmB,IAAAA,OAAAA,CAAAA,kBAAAA,EAAAA,QAAAA,CAAAA;AAGIC,MAAAA,YAAAA,EAAAA,YAAAA;AACAC,MAAAA,cAAAA,EAAAA,cAAAA;AACAL,MAAAA,cAAAA,EAAAA,cAAAA;AACAM,MAAAA,eAAAA,EAAAA,eAAAA;AACAC,MAAAA,MAAAA,EAAAA,MAAAA;AACF,KAAA,CAAA,CAAA,CAAA;AAEF,IAAA,OAAA,YAAA;AACQ,MAAA,IAAA,IAAA,GAAA,MAAA,CAAA,IAAA;;AACN,MAAA,IAAA,SAAA,GAAA,CAAA,cAAA,CAAA,KAAA,EAAA,IAAA,CAAA,KAAA,CAAA,IAAA,CAAA,CAAA,CAAA;AAEA,MAAA,IAAA,OAAA,GAAAC,WAAA,CAAA,KAAA,EAAAC,UAAA,CAAA;;;;AAC6C,QAAA,OAAA,EAAA,qBAAA,CAAA,KAAA;AACP,OAAA,EAAA,CAAAD,WAAA,CAAA,KAAA,EAAA;AAAA,QAAA,OAAA,EAAA,EAAA,CAAA,MAAA,CAAA,4BAAA,CAAA,KAAA,EAAA,UAAA,CAAA;;;AAStC,MAAA,IAAA,UAAA,EAAA;;AACiC,UAAA,SAAA,EAAA,SAAA,QAAA,GAAA;AAAA,YAAA,OAAA,CAAA,OAAA,CAAA,CAAA;AAAA,WAAA;AAAA,SAAA,CAAA,CAAA;AACjC,OAAA;AAEO,MAAA,OAAA,OAAA,CAAA;;AAEX,GAAA;AACF,CAAA,CAAA;;;;"}