🐛 1. 长按滚动条滑动无法实时显示按钮的问题

🎨 2.优化节流和返回顶部动画
This commit is contained in:
sight 2021-12-23 04:14:24 +08:00
parent c6d823c751
commit 33a1931721
2 changed files with 32 additions and 16 deletions

View File

@ -21,7 +21,7 @@
<template> <template>
<!-- 使用默认插槽自定义 --> <!-- 使用默认插槽自定义 -->
<lay-tooltip content="插槽自定义 backtop " position="left"> <lay-tooltip content="插槽自定义 backtop " position="left">
<lay-backtop target=".layui-body" :showHeight="0" :bottom="160" bgcolor="#5FB878" circular disabled> <lay-backtop @click="handlerClick" target=".layui-body" :showHeight="0" :bottom="160" bgcolor="#5FB878" circular disabled>
<lay-icon type="layui-icon-dialogue" size="30px"></lay-icon> <lay-icon type="layui-icon-dialogue" size="30px"></lay-icon>
</lay-backtop> </lay-backtop>
</lay-tooltip> </lay-tooltip>

View File

@ -68,10 +68,12 @@ const emit = defineEmits(['click']);
const backtopRef = ref<HTMLElement | null>(null); const backtopRef = ref<HTMLElement | null>(null);
const scrollTarget = shallowRef<Window | HTMLElement | undefined>(undefined); const scrollTarget = shallowRef<Window | HTMLElement | undefined>(undefined);
let visible = ref(props.showHeight === 0); let visible = ref(props.showHeight === 0);
const borderRadius = computed(() => { const borderRadius = computed(() => {
if (props.circular) return "50%"; if (props.circular) return "50%";
return typeof props.borderRadius === 'number' ? `${props.borderRadius}px` : props.borderRadius; return typeof props.borderRadius === 'number' ? `${props.borderRadius}px` : props.borderRadius;
}); });
const styleBacktop = computed(() => { const styleBacktop = computed(() => {
return { return {
position: props.position, position: props.position,
@ -84,20 +86,29 @@ const styleBacktop = computed(() => {
} }
}); });
// TODO const easeInOut = (value: number): number => {
return value < 0.5 ? 2 * value * value : 1 - 2 * (value - 1) * (value - 1);
}
const scrollToTop = () => { const scrollToTop = () => {
if (!scrollTarget.value) return; if (!scrollTarget.value) return;
if (scrollTarget.value instanceof Window) { if (scrollTarget.value instanceof Window) {
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' }); // smooth | instant(default) window.scrollTo({ top: 0, left: 0, behavior: 'smooth' }); // smooth | instant(default)
} else { } else {
let step = scrollTarget.value.scrollTop / 4; const previous: number = Date.now();
if (scrollTarget.value.scrollTop > 0) { const scrollHeight: number = scrollTarget.value.scrollTop;
scrollTarget.value.scrollTop -= Math.max(step, 10); const animationFunc = () => {
setTimeout(() => { if (!scrollTarget.value || scrollTarget.value instanceof Window) return;
scrollToTop(); const elapsed = (Date.now() - previous) / 450;
}, 1000 / 60); if (elapsed < 1) {
scrollTarget.value.scrollTop = scrollHeight * (1 - easeInOut(elapsed));
window.requestAnimationFrame(animationFunc);
} else {
scrollTarget.value.scrollTop = 0;
} }
} }
window.requestAnimationFrame(animationFunc);
}
}; };
const handleScroll = () => { const handleScroll = () => {
@ -138,15 +149,20 @@ const getScrollTarget = () => {
} }
}; };
onMounted(() => { const throttle = (func: Function, wait: number) => {
let timer: any = undefined; var timer: any = null;
scrollTarget.value = getScrollTarget(); return (...args: any) => {
// TODO if (!timer) {
scrollTarget.value.addEventListener('scroll', () => {
clearTimeout(timer);
timer = setTimeout(() => { timer = setTimeout(() => {
handleScroll(); timer = null;
}, 100); func.apply(this, args);
}); }, wait);
}
};
}
onMounted(() => {
scrollTarget.value = getScrollTarget();
scrollTarget.value.addEventListener('scroll', throttle(handleScroll, 300));
}); });
</script> </script>