Home  >  Q&A  >  body text

Vue horizontal scrolling

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.

template

<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>

Javascript

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])
        }
    }
}

Sass

.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

Console output when scrolling down

[100, 0]

This is what it looks like

P粉755863750P粉755863750178 days ago414

reply all(2)I'll reply

  • P粉422227023

    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).

    reply
    0
  • P粉434996845

    P粉4349968452024-03-26 14:25:22

    I tried something similar to yours but it didn't work until I used currentTarget instead of target in event.target.scrollLeft = event.deltaY 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.

    reply
    0
  • Cancelreply