mobile safari touch

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 = [];
    
    $document[0].addEventListener("touchstart", touchHandler.bind(null, "touchstart"), true);
    $document.addEventListener("touchend", touchHandler.bind(null, "touchend"), true);
    /*$(":root").on("touchstart touchend", "button,p,div", function (ev) {
        addMessage(ev.type + " on " + describeTarget(ev.target) + ": " + describeTouch(ev));
        $scope.$digest();
    });*/
    
    $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 '" + $elem.text() + "'";
        var id = $elem.attr("id");
        var str = elem.tagName + " element";
        if (id)
            str += " with id " + id;
        return str;
    }
    
    function describeTouch(event) {
        var ev = event.originalEvent || event,
            touches = ev.changedTouches,
            t = touches[0],
            x = t.clientX,
            y = t.clientY,
            tgt = t.target,
            str = "touch at (" + x + "," + y + ")";
        str += " on " + describeTarget(tgt);
        if (touches.length > 1)
            str += " [first of " + touches.length + " touches]";
        return str;        
    };
});