I want to use the mouse to scroll horizontally icon. I tried it with scrollLeft
in Javascript but the value doesn't change when scrolling. As you scroll, only the deltaY
value changes between 100 and -100.
Does anyone know where the problem is?
It works when I scroll and mouseover the scrollbar, but I want it to work on the entire div container. I'd also like to do this without dependencies/npm-libraries if possible.
<div class="icons flex_center_h flex_between"> <div class="flex_center_h flex_start instIconContainer" @wheel="ScrollIcons($event)"> <FilterIcon v-for="(icon, iconIndex) in rooms[index].description.icons" :key="icon" :icon="rooms[index].description.icons[iconIndex].icon" :customClass="'instIcon'" /> </div> <FilterIcon :customClass="'navIcon'" :icon="'nav'" /> </div>
import { FilterIcon } from '@/components/Elements/' export default { components: { FilterIcon, }, computed: { rooms() { return this.$store.state.rooms } }, methods: { ScrollIcons(event) { event.preventDefault() event.target.scrollLeft += event.deltaY console.log([event.deltaY, event.target.scrollLeft]) } } }
.icons background: $bg width: 80% padding: 0.5rem 0.5rem ::-webkit-scrollbar width: $scrollbarSize height: 0.3rem background: $bg-glow border-radius: $radius_1 ::-webkit-scrollbar-thumb background: $purple border-radius: $radius_1 .instIconContainer width: 70% max-width: calc(40px * 4) max-height: 80px overflow-x: auto .instIcon width: $IconSize height: $IconSize min-width: $IconSize min-height: $IconSize path, circle fill: $purple
[100, 0]
P粉4222270232024-03-26 17:09:38
The problem with your example is that event.target
is not the scrollbar element, but the icon.
Use ref
to ensure you target the correct element. 1
Another option is to bind to the element's scrollLeft
HTML attribute and let Vue handle the DOM updates. You just change the value in the controller.
We use the .camel
modifier to get around the fact that HTML attributes (which we use to bind to properties) are not case sensitive :scroll-left.camel
twenty three
const { createApp, onMounted, reactive, toRefs } = Vue; const { min, max } = Math; createApp({ setup: () => { const state = reactive({ scroller: null, scrollLeft: 0, }); const onWheel = (e) => { state.scrollLeft = state.scroller ? min( state.scroller.scrollWidth - state.scroller.offsetWidth, max(0, e.deltaY + state.scrollLeft) ) : state.scrollLeft; }; return { ...toRefs(state), onWheel }; }, }).mount("#app");
#app div span { min-width: 50%; display: inline-block; } #app div { display: flex; overflow-x: auto; cursor: ew-resize; }
sssccc
Comments:
1 - Since we're binding to the scrollLeft
property, we don't need the ref
anymore . I kept it because I wanted to limit the controller scrollLeft
value to valid values and needed the ref
to calculate the maximum value.
2 - Technically, it should be :scroll-left.camel.prop
, since it's an HTML property, But it also works without .prop
modifier
3 - .scroll-left.camel
also applies (: abbreviation for scroll-left.camel.prop
).
P粉4349968452024-03-26 14:25:22
I tried something similar to yours but it didn't work until I used currentTarget
In your ScrollIcons method. This way, when you use the mouse wheel while the cursor is hovering over the icon, you will target the containing div or label instead of the icon. In other words, as long as your cursor is within the containing div and the mouse wheel, the div should respond regardless of any other elements between the div and the mouse cursor. instead of
target in
event.target.scrollLeft = event.deltaY