| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import useTagsViewStore from '@/store/modules/tagsView' |
| | | import { TagView } from 'vue-router' |
| | | import useTagsViewStore from '@/store/modules/tagsView'; |
| | | import { TagView } from 'vue-router'; |
| | | const tagAndTagSpacing = ref(4); |
| | | |
| | | const scrollContainerRef = ref<ElScrollbarInstance>() |
| | | const scrollContainerRef = ref<ElScrollbarInstance>(); |
| | | const scrollWrapper = computed(() => scrollContainerRef.value?.$refs.wrapRef as any); |
| | | |
| | | onMounted(() => { |
| | | scrollWrapper.value?.addEventListener('scroll', emitScroll, true) |
| | | }) |
| | | scrollWrapper.value?.addEventListener('scroll', emitScroll, true); |
| | | }); |
| | | onBeforeUnmount(() => { |
| | | scrollWrapper.value?.removeEventListener('scroll', emitScroll) |
| | | }) |
| | | scrollWrapper.value?.removeEventListener('scroll', emitScroll); |
| | | }); |
| | | |
| | | const handleScroll = (e: WheelEvent) => { |
| | | const eventDelta = (e as any).wheelDelta || - e.deltaY * 40 |
| | | const $scrollWrapper = scrollWrapper.value; |
| | | $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4 |
| | | } |
| | | const emits = defineEmits(['scroll']) |
| | | const eventDelta = (e as any).wheelDelta || -e.deltaY * 40; |
| | | const $scrollWrapper = scrollWrapper.value; |
| | | $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4; |
| | | }; |
| | | const emits = defineEmits(['scroll']); |
| | | const emitScroll = () => { |
| | | emits('scroll') |
| | | } |
| | | emits('scroll'); |
| | | }; |
| | | |
| | | const tagsViewStore = useTagsViewStore() |
| | | const tagsViewStore = useTagsViewStore(); |
| | | const visitedViews = computed(() => tagsViewStore.visitedViews); |
| | | |
| | | const moveToTarget = (currentTag: TagView) => { |
| | | const $container = scrollContainerRef.value?.$el |
| | | const $containerWidth = $container.offsetWidth |
| | | const $scrollWrapper = scrollWrapper.value; |
| | | const $container = scrollContainerRef.value?.$el; |
| | | const $containerWidth = $container.offsetWidth; |
| | | const $scrollWrapper = scrollWrapper.value; |
| | | |
| | | let firstTag = null |
| | | let lastTag = null |
| | | let firstTag = null; |
| | | let lastTag = null; |
| | | |
| | | // find first tag and last tag |
| | | if (visitedViews.value.length > 0) { |
| | | firstTag = visitedViews.value[0] |
| | | lastTag = visitedViews.value[visitedViews.value.length - 1] |
| | | // find first tag and last tag |
| | | if (visitedViews.value.length > 0) { |
| | | firstTag = visitedViews.value[0]; |
| | | lastTag = visitedViews.value[visitedViews.value.length - 1]; |
| | | } |
| | | |
| | | if (firstTag === currentTag) { |
| | | $scrollWrapper.scrollLeft = 0; |
| | | } else if (lastTag === currentTag) { |
| | | $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth; |
| | | } else { |
| | | const tagListDom: any = document.getElementsByClassName('tags-view-item'); |
| | | const currentIndex = visitedViews.value.findIndex((item) => item === currentTag); |
| | | let prevTag = null; |
| | | let nextTag = null; |
| | | |
| | | for (const k in tagListDom) { |
| | | if (k !== 'length' && Object.hasOwnProperty.call(tagListDom, k)) { |
| | | if (tagListDom[k].dataset.path === visitedViews.value[currentIndex - 1].path) { |
| | | prevTag = tagListDom[k]; |
| | | } |
| | | if (tagListDom[k].dataset.path === visitedViews.value[currentIndex + 1].path) { |
| | | nextTag = tagListDom[k]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (firstTag === currentTag) { |
| | | $scrollWrapper.scrollLeft = 0 |
| | | } else if (lastTag === currentTag) { |
| | | $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth |
| | | } else { |
| | | const tagListDom: any = document.getElementsByClassName('tags-view-item'); |
| | | const currentIndex = visitedViews.value.findIndex(item => item === currentTag) |
| | | let prevTag = null |
| | | let nextTag = null |
| | | // the tag's offsetLeft after of nextTag |
| | | const afterNextTagOffsetLeft = nextTag.offsetLeft + nextTag.offsetWidth + tagAndTagSpacing.value; |
| | | |
| | | for (const k in tagListDom) { |
| | | if (k !== 'length' && Object.hasOwnProperty.call(tagListDom, k)) { |
| | | if (tagListDom[k].dataset.path === visitedViews.value[currentIndex - 1].path) { |
| | | prevTag = tagListDom[k]; |
| | | } |
| | | if (tagListDom[k].dataset.path === visitedViews.value[currentIndex + 1].path) { |
| | | nextTag = tagListDom[k]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // the tag's offsetLeft after of nextTag |
| | | const afterNextTagOffsetLeft = nextTag.offsetLeft + nextTag.offsetWidth + tagAndTagSpacing.value |
| | | |
| | | // the tag's offsetLeft before of prevTag |
| | | const beforePrevTagOffsetLeft = prevTag.offsetLeft - tagAndTagSpacing.value |
| | | if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { |
| | | $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth |
| | | } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { |
| | | $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft |
| | | } |
| | | // the tag's offsetLeft before of prevTag |
| | | const beforePrevTagOffsetLeft = prevTag.offsetLeft - tagAndTagSpacing.value; |
| | | if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { |
| | | $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth; |
| | | } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { |
| | | $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft; |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | |
| | | defineExpose({ |
| | | moveToTarget, |
| | | }) |
| | | moveToTarget |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |