Skip to content

Commit 566760c

Browse files
committed
refactor: optimize body dimensions calculation in BodyScrollbar component
1 parent 7a81c32 commit 566760c

File tree

1 file changed

+43
-40
lines changed

1 file changed

+43
-40
lines changed

src/components/BodyScrollbar.vue

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@ import type { CSSProperties } from 'vue';
33
44
const { y, x } = useWindowScroll();
55
const { height: winH, width: winW } = useWindowSize();
6-
const body = useElementBounding(document.body);
6+
const [bodyH, bodyW] = (() => {
7+
const body = useElementSize(document.body);
8+
// 不知道为什么得到的 w/h 比实际 clientHeight/clientWidth 多出 0.2 或 0.4, 使用 Math.floor 去除
9+
return [
10+
computed(() => Math.floor(body.height.value)),
11+
computed(() => Math.floor(body.width.value)),
12+
];
13+
})();
714
8-
const yShow = computed(() => body.height.value > winH.value);
15+
const yShow = computed(() => bodyH.value > winH.value);
916
const yHeight = computed(() => {
10-
const clientHeight = body.height.value;
11-
const bodyHeight = clientHeight;
12-
return (winH.value / bodyHeight) * winH.value;
17+
return (winH.value / bodyH.value) * winH.value;
1318
});
1419
const translateY = computed(() => {
15-
const clientHeight = body.height.value;
1620
const height = yHeight.value;
17-
return (y.value / (clientHeight - winH.value)) * (winH.value - height);
21+
return (y.value / (bodyH.value - winH.value)) * (winH.value - height);
1822
});
1923
const yStyle = computed<CSSProperties>(() => {
2024
if (!yShow.value) return {};
@@ -28,10 +32,8 @@ const clickBoxY = async (e: MouseEvent) => {
2832
yHeight.value *
2933
0.9 *
3034
(e.clientY < yHeight.value + translateY.value ? -1 : 1);
31-
const clientHeight = body.height.value;
32-
const bodyHeight = clientHeight;
33-
const height = (winH.value / bodyHeight) * winH.value;
34-
y.value += (deltaY / (winH.value - height)) * (clientHeight - winH.value);
35+
const height = (winH.value / bodyH.value) * winH.value;
36+
y.value += (deltaY / (winH.value - height)) * (bodyH.value - winH.value);
3537
};
3638
const yDragging = shallowRef(false);
3739
let lastYEvent: MouseEvent | undefined = undefined;
@@ -43,27 +45,21 @@ useEventListener('pointermove', (e) => {
4345
if (!lastYEvent) return;
4446
const deltaY = e.clientY - lastYEvent.clientY;
4547
lastYEvent = e;
46-
const clientHeight = body.height.value;
47-
const bodyHeight = clientHeight;
48-
const height = (winH.value / bodyHeight) * winH.value;
49-
y.value += (deltaY / (winH.value - height)) * (clientHeight - winH.value);
48+
const height = (winH.value / bodyH.value) * winH.value;
49+
y.value += (deltaY / (winH.value - height)) * (bodyH.value - winH.value);
5050
});
5151
useEventListener('pointerup', () => {
5252
lastYEvent = undefined;
5353
yDragging.value = false;
5454
});
5555
56-
// 不知道为什么 body_width 比 win_width 多出 0.2 或 0.4, 使用 Math.floor 去除
57-
const xShow = computed(() => Math.floor(body.width.value) > winW.value);
56+
const xShow = computed(() => bodyW.value > winW.value);
5857
const xWidth = computed(() => {
59-
const clientWidth = body.width.value;
60-
const bodyWidth = clientWidth;
61-
return (winW.value / bodyWidth) * winW.value;
58+
return (winW.value / bodyW.value) * winW.value;
6259
});
6360
const translateX = computed(() => {
64-
const clientWidth = body.width.value;
6561
const width = xWidth.value;
66-
return (x.value / (clientWidth - winW.value)) * (winW.value - width);
62+
return (x.value / (bodyW.value - winW.value)) * (winW.value - width);
6763
});
6864
const xStyle = computed<CSSProperties>(() => {
6965
if (!xShow.value) return {};
@@ -76,11 +72,10 @@ const xStyle = computed<CSSProperties>(() => {
7672
const clickBoxX = (e: MouseEvent) => {
7773
const deltaX =
7874
xWidth.value * 0.9 * (e.clientX < xWidth.value + translateX.value ? -1 : 1);
79-
const clientWidth = body.width.value;
80-
const bodyWidth = clientWidth;
81-
const width = (winW.value / bodyWidth) * winW.value;
75+
76+
const width = (winW.value / bodyW.value) * winW.value;
8277
const newX =
83-
x.value + (deltaX / (winW.value - width)) * (clientWidth - winW.value);
78+
x.value + (deltaX / (winW.value - width)) * (bodyW.value - winW.value);
8479
x.value = newX;
8580
};
8681
const xDragging = shallowRef(false);
@@ -93,10 +88,9 @@ useEventListener('pointermove', (e) => {
9388
if (!lastXEvent) return;
9489
const deltaX = e.clientX - lastXEvent.clientX;
9590
lastXEvent = e;
96-
const clientWidth = body.width.value;
97-
const bodyWidth = clientWidth;
98-
const width = (winW.value / bodyWidth) * winW.value;
99-
x.value += (deltaX / (winW.value - width)) * (clientWidth - winW.value);
91+
92+
const width = (winW.value / bodyW.value) * winW.value;
93+
x.value += (deltaX / (winW.value - width)) * (bodyW.value - winW.value);
10094
});
10195
useEventListener('pointerup', () => {
10296
lastXEvent = undefined;
@@ -108,28 +102,33 @@ useEventListener('selectstart', (e) => {
108102
e.preventDefault();
109103
}
110104
});
105+
const bodyHoverd = useElementHover(document.body);
111106
</script>
112107
<template>
113-
<div fixed z-2000 class="BodyScrollbar">
108+
<div v-if="yShow || xShow" class="BodyScrollbar" fixed z-2000>
114109
<div
115-
v-show="yShow"
110+
v-if="yShow"
116111
scrollbar-y
117112
fixed
118113
right-2px
119114
top-0
120115
bottom-0
121116
w-8px
117+
:data-win-h="winH"
118+
:data-body-h="bodyW"
122119
@pointerdown="pointerdownY"
123120
@click="clickBoxY"
124121
>
125122
<div
126123
w-full
127-
bg="#909399"
128-
opacity-30
129-
hover:opacity="50"
124+
rounded-4px
125+
transition-colors
126+
bg="#9093994c"
127+
hover:bg="#9093997f"
130128
:style="yStyle"
131129
:class="{
132-
'opacity-50': yDragging,
130+
'bg-#9093997f': yDragging,
131+
'bg-#0000!': !bodyHoverd,
133132
}"
134133
@click.stop
135134
/>
@@ -142,17 +141,21 @@ useEventListener('selectstart', (e) => {
142141
left-0
143142
right-0
144143
h-8px
144+
:data-win-w="winW"
145+
:data-body-w="bodyW"
145146
@pointerdown="pointerdownX"
146147
@click="clickBoxX"
147148
>
148149
<div
149150
h-full
150-
bg="#909399"
151-
opacity-30
152-
hover:opacity="50"
151+
rounded-4px
152+
transition-colors
153+
bg="#9093994c"
154+
hover:bg="#9093997f"
153155
:style="xStyle"
154156
:class="{
155-
'opacity-50': xDragging,
157+
'bg-#9093997f': xDragging,
158+
'bg-#0000!': !bodyHoverd,
156159
}"
157160
@click.stop
158161
/>

0 commit comments

Comments
 (0)