OnsenUI | Working With Touch Gestures

Written by on April 9, 2015

OnsenUI | Working With Touch Gestures

Time will come when you would need to provide touch gestures over some elements in your application. Or you would want to initiate particular action when application page is swiped or pinched.

While AngularJS provides only a few basic touch events, OnsenUI through Hammer.js provides much more than that (hold, tap, double-tap, dragging events, swiping events, pinch events, transform, rotate). These events are available to you at any point and in any case.

Before we can start, you need to know that two possible approaches are available. In the first case, you can add events directly to directives, skipping non-necessary JavaScript coding. Or you can add them programmatically using jQuery. This article will show you how to do this in few simple steps.

Note: If this tutorial was helpful, you need further clarification, something is not working or you have a request for another Ionic post? Furthermore, leave me a comment below if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com. Thanks and have a nice day!

Table of Contents

[spoiler title=” Click here if you want to see other tutorials, this is the 13th tutorial out of 13 total.”]

[/spoiler]

Intro

To detect a touch gestures, you must wrap the container DOM element using ons-gesture-detector component:

<ons-gesture-detector ng-swipeleft="onSwipeLeft()">
  <div id="detect-area" style="width: 100px; height: 100px;">
    Swipe Here
  </div>
</ons-gesture-detector>
$scope.onSwipeLeft= function() {
    // Do something on swipe left
}

Another way requires only jQuery though some of you may dislike it because it requires a DOM access:

$(document).on('swipeleft', '#detect-area', function() {
  console.log('Swipe left is detected.');
})

Example

A short walk through, when this example initializes try any touch gesture inside a page content and see what would happen.

Demo

Embedded working example

Ionic Framework Pull To Refresh Example

HTML:

<html>

<head>
  <script src="https://code.angularjs.org/1.3.0/angular.js"></script>
  <script src="http://onsenui.io/OnsenUI/build/js/onsenui.js"></script>
  <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
  <script src="script.js"></script>
  <link rel="stylesheet" href="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.2.2/build/css/onsenui.css" />
  <link rel="stylesheet" href="https://cdn.rawgit.com/OnsenUI/OnsenUI/1.2.2/build/css/onsen-css-components.css" />
</head>

<body ng-controller="ListCtrl">

  <ons-navigator animation="slide" var="app.navi">
    
    <ons-page>
     
      <ons-toolbar class="toolbar-black">
        <div class="center">OnsenUI Touch Gestures Example</div>
      </ons-toolbar>
      
      <ons-gesture-detector ng-swipeleft="onGesture('Swipe Left')"
                            ng-swiperight="onGesture('Swipe Right')"
                            ng-swipedown="onGesture('Swipe Down')"
                            ng-swipeup="onGesture('Swipe Up')"
                            ng-hold="onGesture('Hold')"
                            ng-doubletap="onGesture('Double Tap')">
        
        <div id="detect-area" style="width: 100%; height: 100%;">
          <h2 style="text-align: center;">Use any touch gesture on this page</h2> 
          <h2 style="text-align: center;">Used touch gesture: {{gesture.used}}</h2>  
        </div>
        
      </ons-gesture-detector>      

    </ons-page>
    
  </ons-navigator>


</body>

</html>

JavaScript:

var module = ons.bootstrap('my-app', ['onsen']);

module.controller('ListCtrl', function($scope, $timeout) {

  $scope.gesture = {
    used: ''
  };  

  $scope.onGesture = function(gesture) {
    $scope.$apply(function() {
      $scope.gesture.used = gesture;
      console.log(gesture);
    })  
  } 
  
  $(document).on('tap', '#detect-area', function() {
    $scope.$apply(function() {
      $scope.gesture.used = 'Tap';
      console.log('Tap.');
    })      
  })  
  
});

Walkthrough

There’s nothing unique or complex about this example.

The first solution uses event binding inside a directive:

<ons-gesture-detector ng-swipeleft="onGesture('Swipe Left')"
                      ng-swiperight="onGesture('Swipe Right')"
                      ng-swipedown="onGesture('Swipe Down')"
                      ng-swipeup="onGesture('Swipe Up')"
                      ng-hold="onGesture('Hold')"
                      ng-doubletap="onGesture('Double Tap')">
        
  <div id="detect-area" style="width: 100%; height: 100%;">
    <h2 style="text-align: center;">Use any touch gesture on this page</h2> 
    <h2 style="text-align: center;">Used touch gesture: {{gesture.used}}</h2>  
  </div>
        
</ons-gesture-detector>  

A great thing about this approach is that you don’t need to include Hammer.js, it’s already included. Here you can find a full list of all available events. You can, of course, use a separate function for every event.

Second solution is a jQuery one:

$(document).on('tap', '#detect-area', function() {
  $scope.$apply(function() {
    $scope.gesture.used = 'Tap';
    console.log('Tap.');
  })      
})  

Thanks to jQuery on function you don’t need to worry if element is part of the DOM or not (delegated binding). $scope.$apply is needed to start a scope variable update when an event triggers. If you want to remove an event programmatically just use jQuery off method.

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.



Categories

2 thoughts on “OnsenUI | Working With Touch Gestures”

  1. One more important thing that i “detect-area”. If I define its style with width & height by percent such as 80%, it is difficult to detect gesture on real Device. But if I define it with certain pixel such as 400px, it working on real Device. I donot know the reason 🙁
    Below is my working example code :

    Swipe here

Leave a Reply