Dragging

Why you should not implement dragging

For the record, I am 99% against adding drag functionality for your horizontal content.

  1. Touch capable already has the ability to drag (with their finger) without custom implementation.
    • Pick up a touch capable device and try it yourself.
  2. Devices that comes with trackpad can scroll (with two finger) horizontally just as you would with touch screen.
  3. Manipulation of mouse event unnatural to what the user expect might cause unwarranted side effects.
    • Unable to select content, as they would trigger drag start event.
    • Unable to click on content, as they would trigger drag start event.
  4. You could just use a scrollbar.
  5. It's very tiring to repeatedly navigate on a website that has to drag their content.
    • Click, hold, scrubbing to content, hand cramp, carpal tunnel, release, annoyed, poor ux
    • Compared to click to navigate, much much much simple.
  6. Keeping the code simple.

Nevertheless, if you insist, here is how you can do it. Code is inspired by Draccano with his pr into another repo.

Basic example

This is an extremely basic example, it doesn't account for scroll acceleration, deceleration, snapping or smooth scroll.

0

1

2

3

4

5

6

7

8

9

10

11

Dragging.vueimport=recipes/dragging/recipes-dragging.vue
<template>
  <div @mousedown.left="onMouseDown">
    <vue-horizontal responsive class="horizontal" ref="horizontal" snap="none" :button="false"
                    @scroll="onScroll">
      <placeholder-component v-for="i in [0,1,2,3,4,5,6,7,8,9,10,11]" :key="i">
        {{ i }}
      </placeholder-component>
    </vue-horizontal>
  </div>
</template>

<script>
export default {
  data() {
    return {
      left: 0,
      originX: 0,
      originLeft: 0,
    }
  },
  destroyed() {
    this.onMouseUp()
  },
  methods: {
    onScroll({left}) {
      this.left = left
    },
    onMouseDown(e) {
      this.originX = e.pageX
      this.originLeft = this.left

      window.addEventListener("mouseup", this.onMouseUp);
      window.addEventListener("mousemove", this.onMouseMove);
    },
    onMouseUp() {
      window.removeEventListener("mouseup", this.onMouseUp);
      window.removeEventListener("mousemove", this.onMouseMove);
    },
    onMouseMove(e) {
      const offset = e.pageX - this.originX
      const left = this.originLeft - offset
      this.$refs.horizontal.scrollToLeft(left, 'auto')
    }
  }
}
</script>

<style scoped>
.horizontal {
  cursor: move;
  user-select: none;
}

.horizontal >>> .v-hl-container {
  scroll-behavior: initial;
}
</style>