mobile safari touch

by provegard

HTML

<script src="https://code.angularjs.org/1.4.3/angular.js"></script>
<div ng-controller="TestController">
    <p>
        Touch test
        <br/><br/>
    </p>
    <div id="button-container">
        <button ng-click="onButtonClick()">A button</button>
        <br/><br/>
    </div>
    <div>
        <button ng-click="clearMessages()">Clear messages</button>
        <ul>
            <li ng-repeat="msg in messages">{{msg.message}}</li>
        </ul>
    </div>
</div>

JavaScript

m = angular.module("myApp", []);

m.controller("TestController", function ($scope, $document) {
    var msgId = 0;
    $scope.messages = [];

    var x, y, t;
    
    window.addEventListener('touchstart', function (e) {
        x = e.touches[0].clientX;
        y = e.touches[0].clientY;
    }, true);

    window.addEventListener('touchmove', function (e) {
        x = e.touches[0].clientX;
        y = e.touches[0].clientY;
    }, true);

    window.addEventListener('touchend', function (e) {
        t = new Date();
    }, true);

    window.addEventListener('click', function (e) {
         // 1000ms is longer than 300ms. Google suggest 2500, but I'm not sure
         // on what basis. That seems unnecessarily long.
        var time_threshold = 1000,
            // 30px is the distance you can move your finger on the iPad before
            // the "tap" does not generate a click.
            // (it's also the threshold used by zepto before a tap becomes a
            // swipe)
            space_threshold = 30;

        if (new Date() - t <= time_threshold &&
            Math.abs(e.clientX - x) <= space_threshold &&
            Math.abs(e.clientY - y) <= space_threshold) {

            e.stopPropagation();
            e.preventDefault();
        }
    }, true);

    
    $scope.clearMessages = function () { $scope.messages.length = 0; }
    $scope.onButtonClick = addMessage.bind(null, "button click");

    function addMessage(msg) {
        $scope.messages.push({ message: Date.now() + ": " + msg, id: ++msgId });
    }
    
    /*function touchHandler(type, nativeEvent) {
        addMessage(type + " on " + describeTarget(nativeEvent.target) + ": " + describeTouch(nativeEvent));
        $scope.$digest();    
    }*/
    
    function describeTarget(elem) {
        var $elem = angular.element(elem);
        if (elem.tagName == "BUTTON")
            return "BUTTON with text '" + $elem.text() + "'";
        if (elem.tagName == "A")
            return "ANCHOR with text...