🐛 [Bug]: [slider] Slider component vertical mode, drag to the anchor will jump
Version
opentiny/[email protected]
Vue Version
3
Link to minimal reproduction
https://opentiny.design/tiny-vue/zh-CN/os-theme/components/slider
Step to reproduce
-
滚动到下面
-
点击锚点
What is expected
No response
What is actually happening
No response
Any additional comments (optional)
No response
Bot detected the issue body's language is not English, translate it automatically.
Title: 🐛 [Bug]: Slider component in vertical mode, dragging to the anchor point will jump
It seems that the component didn’t calculate the position after scroll
// renderless/src/slider/index.ts
// bindMouseDown()
+ api.bindResize()
const currentValue = api.calculateValue(event)
It seems that the component didn’t calculate the position after scroll
// renderless/src/slider/index.ts // bindMouseDown() + api.bindResize() const currentValue = api.calculateValue(event)
@Huauauaa
I think more critical is this code in packages\renderless\src\slider\index.ts#calculateValue :
(event) => {
let currentValue = 0
if (state.sliderSize == 0) {
const handleEl = vm.$refs.slider
state.sliderSize = handleEl['client' + (props.vertical ? 'Height' : 'Width')]
state.sliderOffset = handleEl.getBoundingClientRect()
}
const offset = state.sliderOffset as DOMRect
if (event.type === 'touchmove' || event.type === 'touchstart' || event.type === 'touchend') {
if (props.vertical) {
currentValue = props.max - ((event.touches[0].pageY - offset.top) / state.sliderSize) * state.rangeDiff
} else {
currentValue = props.min + ((event.touches[0].pageX - offset.left) / state.sliderSize) * state.rangeDiff
}
} else {
if (props.vertical) {
currentValue = props.max - ((event.pageY - offset.top) / state.sliderSize) * state.rangeDiff
} else {
currentValue = props.min + ((event.pageX - offset.left) / state.sliderSize) * state.rangeDiff
}
}
return currentValue
}
event.pageY is the Y coordinate relative to the entire document, but offset.top which get from Element.getBoundingClientRect() is relative to the Viewport
应该选择使用相对 Viewport 的定位来计算
因为当前没有好办法来准确获取某个Element的相对于document的定位。
这对于鼠标事件event来说,只要把event.pageY改成event.clientY就可以。
但是对于当前锚点元素handleEl来说,为了减少回流,我们不能太频繁地使用Element.getBoundingClientRect()来获取相对于ViewPort的定位。这是需要解决的。
Bot detected the issue body's language is not English, translate it automatically.
You should choose to use positioning relative to the Viewport to calculate
Because there is currently no good way to accurately obtain the positioning of an Element relative to the document.
For the mouse event event, just change event.pageY to event.clientY.
But for the current anchor element handleEl, in order to reduce reflow, we cannot use Element.getBoundingClientRect() too frequently to obtain the position relative to the ViewPort. This needs to be addressed.