👌 1.自动寻找可滚动祖先元素; 2.props circular 修改为 circle 3.优化平滑滚动 4.更新文档示例

This commit is contained in:
sight 2021-12-23 16:53:39 +08:00
parent e35765a9e7
commit 47cc7a54c8
2 changed files with 30 additions and 17 deletions

View File

@ -1,12 +1,11 @@
::: title 基础使用 ::: title 基础使用
###### 回到顶部组件的默认样式,通过滑动来查看页面右下角的正方形按钮。 ###### 回到顶部组件的默认样式,<code>lay-backtop</code> 会自动寻找最近的可滚动祖先元素,也可以使用 target 属性指定触发滚动事件的元素,通过滑动来查看页面右下角的正方形按钮。
::: :::
::: demo ::: demo
<template> <template>
<lay-backtop target=".layui-body"></lay-backtop> <lay-backtop></lay-backtop>
</template> </template>
::: :::
@ -17,18 +16,17 @@
::: demo ::: demo
<!-- 使用默认插槽自定义组件内容,也可以使用组件提供的样式属性快速定义常用样式,样式属性能满足大多数场景,lay-backtop组件可搭配 lay-tooltip 组件使用--> <!-- 使用默认插槽自定义组件内容,也可以使用组件提供的样式属性快速定义常用样式,样式属性能满足大多数场景lay-backtop组件可搭配 lay-tooltip 组件使用-->
<template> <template>
<!-- 使用默认插槽自定义 --> <!-- 使用默认插槽自定义 -->
<lay-tooltip content="插槽自定义 backtop " position="left"> <lay-tooltip content="插槽自定义 backtop " position="left">
<lay-backtop @click="handlerClick" target=".layui-body" :showHeight="0" :bottom="160" bgcolor="#5FB878" circular disabled> <lay-backtop @click="handlerClick" :showHeight="0" :bottom="160" bgcolor="#5FB878" circle 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>
<!-- 使用样式属性自定义 --> <!-- 使用样式属性自定义 -->
<lay-tooltip content="属性自定义 backtop " position="left"> <lay-tooltip content="属性自定义 backtop " position="left">
<lay-backtop target=".layui-body" :bottom="100" bgcolor="#5FB878" icon="layui-icon-up" circular> <lay-backtop :bottom="100" bgcolor="#5FB878" icon="layui-icon-up" circle></lay-backtop>
</lay-backtop>
</lay-tooltip> </lay-tooltip>
</template> </template>
@ -94,7 +92,7 @@ export default {
| opacity | 可选,不透明度 | number | 0.0-1.0 | | opacity | 可选,不透明度 | number | 0.0-1.0 |
| color | 可选,前景颜色 | string | #FFFFFF | | color | 可选,前景颜色 | string | #FFFFFF |
| borderRadius | 可选,添加圆角 | string | 2px(默认) | | borderRadius | 可选,添加圆角 | string | 2px(默认) |
| circular | 可选, 使用圆形按钮 | boolean | true \| false(默认) | circle | 可选, 使用圆形按钮 | boolean | true \| false(默认)
| <strong>图标样式</strong> | | <strong>图标样式</strong> |
| icon | 可选,图标类型 | string | layui-icon-top(默认) | | icon | 可选,图标类型 | string | layui-icon-top(默认) |
| iconSize | 可选,图标大小 | number | 30 | | iconSize | 可选,图标大小 | number | 30 |

View File

@ -43,7 +43,7 @@ export interface LayBacktopProps {
opacity?: number; opacity?: number;
color?: string; color?: string;
borderRadius?: number | string; borderRadius?: number | string;
circular?: boolean; circle?: boolean;
/**图标样式*/ /**图标样式*/
icon?: string; icon?: string;
iconSize?: number; iconSize?: number;
@ -54,13 +54,11 @@ export interface LayBacktopProps {
const props = withDefaults(defineProps<LayBacktopProps>(), { const props = withDefaults(defineProps<LayBacktopProps>(), {
target: 'window', target: 'window',
showHeight: 200, showHeight: 200,
right: 30,
bottom: 40,
icon: 'layui-icon-top', icon: 'layui-icon-top',
iconSize: 30, iconSize: 30,
iconPrefix: 'layui-icon', iconPrefix: 'layui-icon',
disabled: false, disabled: false,
circular: false, circle: false,
}); });
const emit = defineEmits(['click']); const emit = defineEmits(['click']);
@ -70,7 +68,7 @@ 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.circle) return "50%";
return typeof props.borderRadius === 'number' ? `${props.borderRadius}px` : props.borderRadius; return typeof props.borderRadius === 'number' ? `${props.borderRadius}px` : props.borderRadius;
}); });
@ -86,6 +84,7 @@ const styleBacktop = computed(() => {
} }
}); });
// TODO
const easeInOut = (value: number): number => { const easeInOut = (value: number): number => {
return value < 0.5 ? 2 * value * value : 1 - 2 * (value - 1) * (value - 1); return value < 0.5 ? 2 * value * value : 1 - 2 * (value - 1) * (value - 1);
} }
@ -135,7 +134,7 @@ const handlerMouseup = () => {
// //
const getScrollTarget = () => { const getScrollTarget = () => {
if (props.target === 'window') { if (props.target === 'window') {
return window || document.documentElement || document.body; return getScrollParent(backtopRef.value!, false);
} else { } else {
const targetElement = document.querySelector<HTMLElement>(props.target); const targetElement = document.querySelector<HTMLElement>(props.target);
if (!targetElement) throw new Error(`target is not existed: ${props.target}`); if (!targetElement) throw new Error(`target is not existed: ${props.target}`);
@ -147,8 +146,23 @@ const getScrollTarget = () => {
} }
return targetElement; return targetElement;
} }
}; }
//
const getScrollParent = (element: HTMLElement, includeHidden: boolean): HTMLElement => {
let style: CSSStyleDeclaration = getComputedStyle(element);
let excludeStaticParent: boolean = style.position === "absolute";
let overflowRegex: RegExp = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
//if (style.position === "fixed") return document.documentElement || document.body || window;
for (let parent: HTMLElement = element; (parent = parent.parentElement!);) {
style = getComputedStyle(parent);
if (excludeStaticParent && style.position === "static") continue;
if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) return parent;
}
return document.documentElement || document.body || window;
}
//
const throttle = (func: Function, wait: number) => { const throttle = (func: Function, wait: number) => {
var timer: any = null; var timer: any = null;
return (...args: any) => { return (...args: any) => {
@ -158,10 +172,11 @@ const throttle = (func: Function, wait: number) => {
func.apply(this, args); func.apply(this, args);
}, wait); }, wait);
} }
}; }
} }
onMounted(() => { onMounted(() => {
if (!props.target) return;
scrollTarget.value = getScrollTarget(); scrollTarget.value = getScrollTarget();
scrollTarget.value.addEventListener('scroll', throttle(handleScroll, 300)); scrollTarget.value.addEventListener('scroll', throttle(handleScroll, 300));
}); });