Enable tap, swipe, touch, hold, mouse down, mouse up events on any HTML DOM Element in vue.js 3.x.

Overview

vue3-touch-events

Enable tap, swipe, touch, hold, mouse down, mouse up events on any HTML DOM Element in vue.js 3.x.

The easiest way to make your interactive vue.js content mobile-friendly. When you add v-touch events to your elements, it works on desktop and mobile using a fully declarative syntax. Unlike other libraries, you do not need to add any special code to your components to make this work. You simply have to register the library globally and it enables new events throughout your application.

Events

Released under the permissive MIT License.

Features:

  • Declarative syntax for common touch events, such as tap, swipe, hold, drag and more
  • All events support desktop (mouse) and mobile devices (touch screen) with the same syntax
  • Automatically add styling on hover and tap using v-touch-class directive
  • Bind multiple touch events on one DOM element
  • Customizable events with native-like events handler
  • Throttling for drag and rollover events to prevent crashing your application
  • Global configuration that applies to all events in the application
  • Ability to override global configuration on any element using v-touch-options directive
  • Bindings for TypeScript included and also works in pure-JavaScript projects

Version:

Note: This library is for vue.js 3.x only. For vue.js 2.x see the older library.

Credits:

  • All credits go to Jerry Bendy for creating the original project vue2-touch-events
  • Special thanks to Xavier Julien for creating the Vue 3.x port

Installation

To install with npm:

npm install vue3-touch-events

To install with yarn:

yarn add vue3-touch-events

TypeScript

You need to register this plugin with vue.js in your main application file:

import Vue from "vue";
import Vue3TouchEvents from "vue3-touch-events";

Vue.use(Vue3TouchEvents);

JavaScript

You need to include the UMD script of this plugin and you do not need to register this plugin with vue.js.

">
<script src="libs/vue.js">script>
<script src="libs/vue3-touch-events.js">script>

Examples

In your .vue component files, use the v-touch directive add touch events to elements.

Specify the event using the first argument, for example v-touch:tap or v-touch:swipe.

Tap Me Tap Me Swipe Here Swipe Left Here Long Tap Event Press and Release Events Triggered once when starting to move and tapTolerance is exceeded Continuously triggered while dragging Touch and hold on the screen for a while Mix Multiple Events Different options Customize touch class Customize touch class">

<span v-touch:tap="touchHandler">Tap Mespan>


<span v-touch="touchHandler">Tap Mespan>


<span v-touch:swipe="swipeHandler">Swipe Herespan>


<span v-touch:swipe.left="swipeHandler">Swipe Left Herespan>


<span v-touch:longtap="longtapHandler">Long Tap Eventspan>


<span v-touch:press="startHandler" v-touch:release="endHandler">Press and Release Eventsspan>  <span v-touch:drag.once="movedHandler">Triggered once when starting to move and tapTolerance is exceededspan> <span v-touch:drag="movingHandler">Continuously triggered while draggingspan>  <span v-touch:hold="touchHoldHandler">Touch and hold on the screen for a whilespan>  <span v-touch:tap="tapHandler" v-touch:longtap="longtapHandler" v-touch:swipe.left="swipeLeftHandler" v-touch:press="startHandler" v-touch:release="endHandler" v-touch:swipe.right="swipeRightHandler">Mix Multiple Eventsspan>  <span v-touch:tap="tapHandler" v-touch-options="{touchClass: 'active', swipeTolerance: 80, touchHoldTolerance: 300}">Different optionsspan>  <span v-touch:tap="tapHandler" v-touch-class="active">Customize touch classspan>  <span v-touch:tap="tapHandler" v-touch-options="{touchClass: 'active'}">Customize touch classspan>

Usage

Simple callback

If you simply want to execute a callback function on a v-touch event, use this pattern:

Button
">
<div v-touch:tap="onTapItem">Buttondiv>
methods: {
	onTapItem(mouseEvent) { // you can remove the `mouseEvent` argument
		console.log("Tapped!");
	},
},

Passing parameters to the event handler

If you want to add extra parameters to your v-touch event handler, you need to return a delegate in the event handler. You can pass as many attributes as you need.

Button
">
<div v-for="(item, i) in items">
	<div v-touch:swipe="onSwipeItem(item, i)">Buttondiv>
div>
methods: {
	onSwipeItem(item, i) {
		return function (direction, mouseEvent) {
			console.log("Swiped item ", i, ": ", item, " in direction ", direction);
		};
	},
},

Events

List of all supported events are given below.

All events work on Desktop & Mobile devices.

Event
Behaviour
v-touch
v-touch:tap
Desktop: Triggered when the user clicks on the element (press and release).
Mobile: Triggered when the user taps on the element (tap and release)
v-touch:longtap Desktop: Triggered when the user holds on the element for longTapTimeInterval MS and then releases it (press and release).
Mobile: Triggered when the user taps and holds on the element for longTapTimeInterval MS and then releases it (tap and release)
v-touch:swipe Triggered when the user drags on the element (swipe).
It will detect the direction of the swipe and send it to your callback.
First argument of the callback must be direction attribute, which can be left, right, top or bottom.
Example callback: onSwipe(direction){ ... }
v-touch:swipe.left
v-touch:swipe.right
v-touch:swipe.top
v-touch:swipe.bottom
Triggered when the user drags on the element in a specific direction (directional swipe).
v-touch:hold Triggered when the user holds the mouse button down for touchHoldTolerance MS while over the element (press and hold).
This will be triggered before your finger is released, similar to what native mobile apps do.
v-touch:press Desktop: Triggered when the user presses the element (mouse down).
Mobile: Triggered when the user taps the element without releasing.
v-touch:drag.once Triggered when the user presses and drags the element.
Only fired once, the moment the user first drags on the element.
v-touch:drag Triggered when the user presses and drags the element.
Fired every time the mouse moves while dragging the element.
This event is throttled to prevent too many events per second.
This event will fire every dragFrequency MS.
v-touch:release Desktop: Triggered when the user releases the element (mouse up).
Mobile: Triggered when the user taps and releases the element.
v-touch:rollover Desktop only: Triggered when the user moves his mouse over the element.
This event is throttled to prevent too many events per second.
This event will fire every rollOverFrequency MS.

Migration from Vue 2.x

Some events have been renamed from the vue 2.x version of this library, in order to expose a cleaner, more consistant and more descriptive naming scheme.

Old event name New event name
v-touch:touchhold v-touch:hold
v-touch:start v-touch:press
v-touch:end v-touch:release
v-touch:moved v-touch:drag.once
v-touch:moving v-touch:drag

System events

These are the default interactivity events supported by vue.js 3.x.

  • You do not need to install this library to use them.
  • They are always available for your usage alongside this library.
  • The system default mousemove event is similar to v-touch:rollover, however the system event is not throttled and it will trigger hundreds of times per second, potentially crashing your application if any logic is performed in the event handler

Desktop devices:

  • v-on:click - Triggered when the user presses and releases the element.
  • v-on:mousedown - Triggered when the user presses the element.
  • v-on:mousemove - Triggered when the user moves the mouse over the element.
  • v-on:mouseup - Triggered when the user presses and releases the element.
  • v-on:mouseenter - Triggered when the user moves his mouse into the element.
  • v-on:mouseleave - Triggered when the user moves his mouse away from the element.

Mobile devices:

  • v-on:touchstart - Triggered when the user presses the element.
  • v-on:touchmove - Triggered when the user presses and drags over the element.
  • v-on:touchcancel - Triggered when the user presses the element, and releases outside the element, thereby cancelling his tap.
  • v-on:touchend - Triggered when the user taps the element (press and release).

Options

These additional directives can be added to each element.

v-touch-options

v-touch-options directive allows you set a different configuration for a specified component. It will override global configurations.

v-touch-class

v-touch-class directive allows you automatically add a class when the element is rolled over (desktop) or tapped (mobile). It overrides the class specified in the global config option touchClass.

  • By default the touchClass is added when the element is pressed (mousedown), and removed when the element is released (mouseup).
  • If desktop events are enabled (disableClick: false), then the touchClass is added on roll over (mouseenter) and roll out (mouseleave) as well.
  • You can use this instead of :active and :hover pseudo classes, as it works on both desktop and mobile

Behaviour:

Device Event name Effect Condition
Desktop only Mouse enter (roll over) `touchClass` added desktop events must be enabled
Mouse leave (roll out) `touchClass` removed desktop events must be enabled
Mobile only Mouse down (press) `touchClass` added
Mouse up (release) `touchClass` removed

For example:

Tap Me">
<span v-touch:tap="touchHandler" v-touch-class="'active'">Tap Mespan>

Now, when you press the element, it will add an extra active class automatically, and when you release the element the class will be removed.

So that you can use this feature to instead of :active and :hover pseudo class, for a better user experience.

/* before */
span:active,
span:hover {
	background: green;
}

/* now, you can write like this */
span.active {
	background: green;
}

Global configuration

Vue.use(Vue3TouchEvents, {
	disableClick: false, ...
});
  • disableClick - Whether to disable desktop events. Default: false.

    Keep the default value or false if your application is used on desktop and mobile devices.

    If your application is only for mobile use, set this to true to get a better user experience, because it can resolve some touch pass-through issues encountered on mobile devices.

  • touchClass - Which CSS class to add while an element is rolled over (desktop) or tapped (mobile). Default: ''

    This is a global config, and you can use v-touch-class directive to override this setting for a single element.

  • tapTolerance in pixels - How many pixels the user must drag on the element for it to register as a tap event. Default: 10 pixels.

  • touchHoldTolerance in milliseconds - The timeout for a hold event. Default: 400 MS

  • swipeTolerance in pixels - How many pixels the user must drag on the element for it to register as a swipe event. Default: 30 pixels.

  • longTapTimeInterval in milliseconds - The minimum time interval to detect whether long tap event effective or not. Default: 400 MS.

  • dragFrequency in milliseconds - How often should drag events be fired. Default: 100 MS (10 times a second).

  • rollOverFrequency in milliseconds - How often should rollover events be fired. Default: 100 MS (10 times a second).

Comments
  • Touch events not bound

    Touch events not bound

    Thanks for creating this library - exactly what I was looking for! However, I can't get it working!

    I installed using npm (npm -i -S vue3-touch-events)

    In my main JS file, I have the following:

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Vue3TouchEvents from 'vue3-touch-events'
    ...
    Vue.use(Vue3TouchEvents)
    
    Vue.use(VueRouter)
    ...
      new Vue({
        router,
        render: h => h(App)
      }).$mount('#app')
    

    Then, in my template I have the following defined:

    <template>
    <div :class="{ 'no-controls': this.$route.path==='/' }">
      <div id="content-container" v-touch:swipe.left="doHideMenu" v-touch:swipe.right="doShowMenu">
        <router-view :playback="playback" @showQueue="toggleQueue" ></router-view>
      </div>
      ...
    </template>
    <script>
    ...
    export default {
      name: 'Main',
      ...
      props: [ 'isLoggedIn' ],
      methods: {
        toggleQueue (fixed = null) {
          this.showQueue = !this.showQueue
        },
        doShowMenu () {true
          this.showMenu = true
        },
        doHideMenu () {
          this.showMenu = false
        }
      }
    }
    </script>
    

    However, the swipe gestures aren't working. When I had a look at the inspector in chrome, I can't see any events bound to the element other than the click and other basic events.

    Any idea what I'm doing wrong?

    Thanks!

    opened by gilphilbert 2
  • Update package.json type

    Update package.json type

    Hello. Thanks for the nice library!

    Without {"type": "module"}, I see this error in VitePress:

    (node:16307) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
    (Use `node --trace-warnings ...` to show where the warning was created)
    build error:
     /home/user/project/node_modules/vue3-touch-events/index.js:416
    export default vueTouchEvents
    ^^^^^^
    
    SyntaxError: Unexpected token 'export'
        at Object.compileFunction (node:vm:360:18)
        at wrapSafe (node:internal/modules/cjs/loader:1048:15)
        at Module._compile (node:internal/modules/cjs/loader:1083:27)
        at Module._extensions..js (node:internal/modules/cjs/loader:1173:10)
        at Module.load (node:internal/modules/cjs/loader:997:32)
        at Module._load (node:internal/modules/cjs/loader:838:12)
        at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
        at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
        at async Promise.all (index 0)
        at async ESMLoader.import (node:internal/modules/esm/loader:527:24)
     ELIFECYCLE  Command failed with exit code 1.
    

    With {"type": "module"}, the component using vue3-touch-events works normally.

    UPD: it got more confusing and I had to replace the import as well: import vueTouchEvents from "vue3-touch-events";

    ~Hopefully, it is OK to merge.~ Let's discuss how to integrate ESM, if possible.

    opened by 6r1d 1
  • TypeError: Cannot read properties of undefined (reading 'getSSRProps')

    TypeError: Cannot read properties of undefined (reading 'getSSRProps')

    I have installed the package on the client side and it works, but when I refresh the page I get an SSR error:

    TypeError: Cannot read properties of undefined (reading 'getSSRProps') at ssrGetDirectiveProps (\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:974:42)

    The import of the package and app.use(Vue3TouchEvents) does not cause the issue.

    The error only appears when I add a directive to the DOM like <li v-touch:swipe.left="next" v-touch:swipe.right="prev">

    How can this package be used with SSR?

    opened by aysiscore 0
  • Why does the plugin, when initializing the page, execute all events hung on each element of the list

    Why does the plugin, when initializing the page, execute all events hung on each element of the list

    Why does the plugin, when initializing the page, execute all events hung on each element of the list, while nothing should happen to these elements at all. And when a new element appears, these events fire again on it. <div v-touch:tap="takeOrder(order)" class="orderCard-wrap">...</div> i use: vite 2.6.4 vue3-touch-events 4.1.0

    opened by Shirockov55 2
  • v-touch:tap gets triggered even if mousedown/touchstart happens outside of the element in a weird scenario

    v-touch:tap gets triggered even if mousedown/touchstart happens outside of the element in a weird scenario

    There's a weird bug I have noticed, that under a certain circunstance the :tap method gets triggered when it should not.

    (There's an option related to this issue called tapTolerance)

    How is it happening?

    Let's call the following flow as "Flow 1"

    1. Mousedown any part of the screen without doing it over the element of interest.
    2. Without releasing the mousedown, go over the element of interest and release the mousedown over the element.
    3. The :tap event gets triggered

    This always happens, until I trigger the tapTolerance condition over the element.

    What do I mean with triggering the tapTolerancecondition?

    Lets say I left the tapTolerance to it's defaults of 10px, if I do the following:

    And let's call the following flow as "Flow 2"

    1. Mouse down over the element of interest
    2. Move the cursor more than 10px
    3. The :tap event does not get triggered

    No matter how many times I repeat the Flow 1 steps, I always get the :tap event triggered, when it shouldn't because I didn't start the click/touch over the element of interest.

    But as soon as I do the Flow 2 steps once, Flow 1 no longers triggers :tap event. This should be the desired behavior all the time.

    opened by c4b4d4 0
  • Is there a way to set the direction of the touch drag event?

    Is there a way to set the direction of the touch drag event?

    Hello I'm making a carousel that displays a blog list. Currently, the problem with this is that the carousel moves along with the touch drag (scroll) while pressing the carousel component.

    I found a way to block the touch slide through the Carousel's plug-in, and I'm going to use it when a scroll event is called. I think I can't use scroll events and wheel events on mobile and I have to use touch move events. So can I call the touch drag event only when I move it up/down (touch scroll)?

    For example, can I use it like 'v-touch:drag.up' or 'v-touch:drag.down'?

    Thank you.

    opened by schosdas 1
  • [Feature request] Add an accepted-cone region to the swipe gesture

    [Feature request] Add an accepted-cone region to the swipe gesture

    When I used this library, I found that the gestures of swiping had to be fairly exact in the wanted direction. In the downloaded plugin index.js I've added a "coneSwipeWidth" option to the plugin which dictates how much a user can move in the perpendicular direction relative to the dominant swiping direction. ConeSwipeWidth_feature_request

    See code attachement. If the user swipes within that cone, then the gesture is still considered to be that direction.

    I've added my version as a file attachment. Line 47 and 129-132 have been added / changed

    opened by rednas174 2
  • Storybook warning

    Storybook warning

    vue3-touch-events doesn't appear to be written in CJS, but also doesn't appear to be a valid ES module (i.e. it doesn't have "type": "module" or an .mjs extension for the entry point). Please contact the package author to fix.

    I seem to be getting this warning in Storybook, which I don't think matter, as the package is working, but still wanted to raise

    opened by doutatsu 0
Owner
Robin Rodricks
Full Stack Software Architect
Robin Rodricks
Directive to be able to attach events through other events on HTML elements in VueJS

vue-attach-event Directive to be able to attach events through other events on HTML elements in VueJS Install NPM: npm i --save vue-attach-event Requi

Aarón J. Montes 0 Jul 8, 2021
Convert HTML DOM Element to PDF

Convert HTML DOM Element to PDF. You can save a specified element as PDF File, print it directly, or preview as PDF.

Emily Wang 0 Jul 29, 2019
Confirmation button for sensitive action, which requires to be hold for an amount of seconds

VueLongpress A VueJS (2.x) button component that requires you to keep pressing to confirm a given action. DEMO Live demo on jsFiddle What is this? A c

Javis V. Pérez 74 Nov 11, 2022
Desktop Postflop is a free, open-source GTO solver for Texas hold'em poker

Desktop Postflop Desktop Postflop is a free, open-source GTO solver for Texas hold'em poker. This is a port of WASM Postflop to a native desktop appli

Wataru Inariba 26 Dec 31, 2022
Render children into a DOM node that exists outside the DOM hierarchy of the parent component

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

Nourse 0 Nov 8, 2018
Google-onetap-signin-client-vue - Vue 3 Demo of using the Google One-Tap Signin in a modular way (Client Code)

vue-google-onetap-signin Project setup npm install Compiles and hot-reloads for

Zensynthium 4 Dec 12, 2022
Prints a specific area/element of your html page for any frontend framework

Prints a specific area/element of your html page for any frontend framework

Trinmar Boado 12 Sep 24, 2022
Vue component to trap the focus within a DOM element

focus-trap-vue Vue component to trap the focus within a DOM element Installation For Vue 2 npm install focus-trap focus-trap-vue For Vue 3 npm install

Eduardo San Martin Morote 169 Jan 1, 2023
Detect DOM element resizing based on Vue3.x

Detect DOM element resizing based on Vue3.x

null 0 Jul 22, 2021
iOS style swipe actions

vue-swipe-actions iOS style swipe actions for Vue.js, Live Demo (Source) Installation npm install --save vue-swipe-actions import { SwipeList, SwipeO

eCollect 214 Nov 23, 2022
Applications for any device with HTML, CSS and JavaScript - free and open source!

App Framework App Framework development has ended. I recommend using the Framework7 CLI instead. iOS and Android Apps with HTML & JavaScript - App Fra

null 646 Dec 28, 2022
PostCSS syntax for parsing HTML (and HTML-like)

PostCSS HTML Syntax PostCSS syntax for parsing HTML (and HTML-like) Vue Single-File Components Svelte Components Astro Components PHP Quick App XSLT G

Yosuke Ota 11 Dec 29, 2022
Resize the font-size in rem units so that the text fits into the html element.

v-fit2box directive for Vue3 Resize the font-size in rem units so that the text fits into the html element. In other words the font size is smaller fo

null 1 Jan 19, 2022
A Vue.js 2 component to clone DOM elements

vue-cloneya A vue component to clone DOM elements Live demo here Install yarn add vue-cloneya # or npm i vue-cloneya Import import Vue from 'vue'

Rida Amirini 15 Aug 27, 2022
An escape hatch for DOM Elements in Vue.js components.

vue-dom-portal An escape hatch for DOM Elements in Vue.js components. The directive v-dom-portal will move DOM Nodes from their current place in a Vue

Caleb Roseland 202 Nov 2, 2022
A vue directive to keep dom ratio

vue-keep-ratio [中文项目介绍] As there comes a new css attribute: aspect-ratio, I picked up my old work vue-keep-ratio, use a more adaptive (but hack) way t

Aiello 6 Sep 13, 2021
A directive-supported plugin for transfering DOM to another location in Vue.js components

A directive-supported plugin for transfering DOM to another location in Vue.js components

Emil Zhai 1 Jul 13, 2019
BEM is a great way to namespace DOM elements

Vue BEM Plugin BEM is a great way to namespace DOM elements. If you're like me, however, you can't stand manually writing __ and -- over and over agai

Mike Schutte 0 Apr 6, 2019
NPM package: a 3D rolling sphere of words following your mouse movements

wordsphere NPM package: a 3D rolling sphere of words following your mouse moveme

Ilan Azoulay 2 Jun 28, 2022