119 lines
2.5 KiB
Vue
119 lines
2.5 KiB
Vue
<template>
|
|
<div class="scroll-buttons-overlay">
|
|
<div
|
|
v-show="showTopBtn"
|
|
class="scroll-btn"
|
|
@click="scrollToTop"
|
|
>
|
|
<el-icon :size="20">
|
|
<ArrowUpBold />
|
|
</el-icon>
|
|
</div>
|
|
<div
|
|
v-show="showBottomBtn"
|
|
class="scroll-btn"
|
|
@click="scrollToBottom"
|
|
>
|
|
<el-icon :size="20">
|
|
<ArrowDownBold />
|
|
</el-icon>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted, onUnmounted } from 'vue'
|
|
import { ArrowUpBold, ArrowDownBold } from '@element-plus/icons-vue'
|
|
|
|
const props = defineProps({
|
|
containerSelector: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
// 控制按钮显示的滚动阈值
|
|
scrollThreshold: {
|
|
type: Number,
|
|
default: 100
|
|
}
|
|
})
|
|
|
|
const showTopBtn = ref(false)
|
|
const showBottomBtn = ref(false)
|
|
|
|
const handleScroll = () => {
|
|
const container = document.querySelector(props.containerSelector)
|
|
if (container) {
|
|
const { scrollTop, scrollHeight, clientHeight } = container as Element
|
|
showTopBtn.value = scrollTop > props.scrollThreshold
|
|
showBottomBtn.value = scrollTop + clientHeight < scrollHeight - 10
|
|
}
|
|
}
|
|
|
|
const scrollToTop = () => {
|
|
const container = document.querySelector(props.containerSelector)
|
|
if (container) {
|
|
container.scrollTo({
|
|
top: 0,
|
|
behavior: 'smooth'
|
|
})
|
|
}
|
|
}
|
|
|
|
const scrollToBottom = () => {
|
|
const container = document.querySelector(props.containerSelector)
|
|
if (container) {
|
|
container.scrollTo({
|
|
top: (container as Element).scrollHeight,
|
|
behavior: 'smooth'
|
|
})
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
const container = document.querySelector(props.containerSelector)
|
|
if (container) {
|
|
container.addEventListener('scroll', handleScroll)
|
|
}
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
const container = document.querySelector(props.containerSelector)
|
|
if (container) {
|
|
container.removeEventListener('scroll', handleScroll)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.scroll-buttons-overlay {
|
|
position: fixed;
|
|
right: calc(50% - 400px - 60px);
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
z-index: 2001;
|
|
|
|
.scroll-btn {
|
|
background-color: var(--el-color-primary);
|
|
color: white;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: 50%;
|
|
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
opacity: 0.8;
|
|
|
|
&:hover {
|
|
background-color: var(--el-color-primary);
|
|
opacity: 1;
|
|
transform: scale(1.1);
|
|
}
|
|
}
|
|
}
|
|
</style> |